﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using App1AppHandler;
using System.Timers;
using System.Drawing;
using System.Reflection;
using Reborn_WorldServer;
using Reborn_WorldServer.App1AppHandler;
using Reborn_WorldServer.App1AppHandler.Spells.Interfaces;

namespace Reborn_Server.App1AppHandler
{
    public class CreatureAI
    {
        //Reference to parent creature
        public Creature MyCreature;

        //public Timer Timer_CreatureRound = new Timer();
        public QueueTimer Timer_CreatureRound = new QueueTimer();

        public Timer Timer_CreatureRespawn = new Timer();

        public delegate void TimerElapsedHandler(object sender);
        //Event that fires when characters round timer elapses (for spells that need to wait until the round is complete)
        public event TimerElapsedHandler RoundElapsed;

        //Used to track when a creature is first encountered or change AI per move pattern
        private int EncounteredCounter = 0;

        private int WarmSpellLevel = 0;

        //Convience field.. stores main game handler from MyCreature.GameHandler
        private AppHandler2 GameHandler;

        //This is used to determine if the creature needs to chase something up or down stairs
        private int numAttackableCreaturesOnStairs = 0;

        //Constructor, requires reference to parent creature
        public CreatureAI(Creature myCreature)
        {
            MyCreature = myCreature;
            GameHandler = MyCreature.GameHandler;

            //Timer_CreatureRound.AutoReset = false;
            //Timer_CreatureRound.Elapsed += new ElapsedEventHandler(Timer_CreatureRound_Elapsed);

            Timer_CreatureRespawn.AutoReset = false;
            Timer_CreatureRespawn.Elapsed += new ElapsedEventHandler(Timer_CreatureRespawn_Elapsed);
        }

        public void forceRespawn()
        {
            Timer_CreatureRespawn.Stop();

            //Async this because it may lock a different map than the one this creature is running in possibly causing a double lock and deadlock.
            Action<object, ElapsedEventArgs> respawnTimerHandler = (Action<object, ElapsedEventArgs>)Timer_CreatureRespawn_Elapsed;
            respawnTimerHandler.BeginInvoke(null, null, null, null);
        }

        //Timer Event Handles Respawn, Resets Creatures, Adds them to map, starts round timer
        private void Timer_CreatureRespawn_Elapsed(object source, ElapsedEventArgs e)
        {
            LockItem MyLock = GameHandler.GetLockItem(MyCreature.MapID, MyCreature.Instance); ;

            
            EncounteredCounter = 0;
            outOfWanderCounter = 0;

            List<Character> CharsToUpdate = new List<Character>();
            List<MapItem> MapItemsToUpdate = new List<MapItem>();

            lock (MyLock.LockObj)
            {
                if (MyCreature.HP > 0)
                    return;

                MyCreature.ResetCreature();

                Map CurrentMap = GameHandler.GetMap(MyCreature.StartMapID, MyCreature.Instance);

                foreach (MapItem mapitem in CurrentMap.MapItems)
                {
                    if (Math.Abs(mapitem.MapX - MyCreature.StartMapX) <= 4 && Math.Abs(mapitem.MapY - MyCreature.StartMapY) <= 4)
                    {
                        foreach (CreatureBase creatureBase in mapitem.CreaturesBases)
                        {
                            if (creatureBase is Character)
                            {
                                Character character = (Character)creatureBase;
                                CharsToUpdate.Add(character);
                            }
                        }
                    }
                    if (mapitem.MapX == MyCreature.StartMapX && mapitem.MapY == MyCreature.StartMapY)
                    {
                        MyCreature.SetPosition(mapitem);
                        mapitem.CreaturesBases.Add(MyCreature);

                        MapItemsToUpdate.Add(mapitem);
                    }
                }
                foreach (Character character in CharsToUpdate)
                {
                    character.AddMapItems(MapItemsToUpdate, false);
                }
            }//End Lock

            //Do not auto restart the AI timer if this is a quest creature
            if (!(MyCreature is QuestCreature))
            {
                Timer_CreatureRound.Interval = 3000;
                Timer_CreatureRound.Start();
            }
        }

        public void runAI()
        {
            lock (MyCreature.creatureLock)
            {
                //Dispatch RoundElapsed Event
                if (RoundElapsed != null)
                    RoundElapsed(this);

                PortalInfo portalTo = null;

                LockItem lockItem = GameHandler.GetLockItem(MyCreature.MapID, MyCreature.Instance);
                lock (lockItem.LockObj)
                {
                    //CHECK IF WE'RE IN A VALID STATE TO CONTINUE EXECUTION/////////////////////////

                    //System.Reflection.MethodBase currentMethodBase = System.Reflection.MethodBase.GetCurrentMethod();
                    //Delegate currentMethodDelegate = Delegate.CreateDelegate(currentMethodBase.GetType(), this, currentMethodBase.Name);

                    //Create a delegate for this method incase it cant be run right now
                    Action thisMethod = (Action)runAI;
                    //Record this method's arguments
                    Object[] thisMethodArgs = { null };
                    //Pass the delegate and args when we check if we're mid map transfer. If yes, they will be recorded and run again automatically.
                    if (this.MyCreature.isChangingMaps(thisMethod, thisMethodArgs) == true)
                        return;

                    //A map transfer happened, but its already complete. Immediately re-run this method on a different thread. 
                    //We need to use a different thread because otherwise the current thread would lock 2 maps possibly resulting in a deadlock.
                    if (this.MyCreature.MapID != lockItem.MapID)
                    {
                        thisMethod.BeginInvoke(null, null);
                        return;
                    }
                    //STATE IS VALID, CONTINUE EXECUTION///////////////////////////////////////////



                    //Check for respawn
                    if (MyCreature.HP < 1)
                    {
                        if (MyCreature.Respawn_Min != -1)
                        {
                            Timer_CreatureRespawn.Interval = MyCreature.Respawn_Min * 60 * 1000;
                            Timer_CreatureRespawn.Start();
                        }
                        return;
                    }

                    //If creatures quest is done, dont do anything, wait for respawn
                    if (MyCreature is QuestCreature)
                    {
                        QuestCreature questCreature = (QuestCreature)MyCreature;
                        if (questCreature.QuestStatus == "Complete")
                        {
                            Timer_CreatureRound.Interval = 3000;
                            Timer_CreatureRound.Start();
                            return;
                        }
                    }

                    //Check for stun
                    if (MyCreature.buffManager.IsStunned() == true)
                    {
                        Timer_CreatureRound.Interval = 3000;
                        Timer_CreatureRound.Start();
                        return;
                    }

                    //Check for fear
                    Buff buff = MyCreature.buffManager.GetBuff("Fear");
                    if (buff != null)
                    {
                        Spell_Fear fear = (Spell_Fear)buff;
                        fear.runAI();
                        Timer_CreatureRound.Interval = 3000;
                        Timer_CreatureRound.Start();
                        return;
                    }

                    if (MyCreature.petController != null)
                    {
                        MyCreature.petController.RunPetAI();

                        //If a summoned pet dies as a result of its own action, it will be dismissed and the timer disposed.
                        try
                        {
                            Timer_CreatureRound.Interval = 3000;
                            Timer_CreatureRound.Start();
                        }
                        catch { }
                        return;
                    }

                    //Ensure that the action that is in queue is valid
                    while (true)
                    {
                        if (MyCreature.attackSequenceManager.CurrentAction is CreatureAttackWeapon)
                            break;
                        if (MyCreature.attackSequenceManager.CurrentAction is CreatureCastSpell)
                        {
                            CreatureCastSpell ccs = (CreatureCastSpell)MyCreature.attackSequenceManager.CurrentAction;
                            
                            //Check if this spell is a self cast spell, if so check if we already have the buff. Skip if we do
                            bool selfCastOk = true;
                            if (ccs.spellIcon.CastType == "Self" && MyCreature.buffManager.GetBuffByStackType(ccs.spellIcon.StackType) != null)
                                selfCastOk = false;

                            if (ccs.Instant == true && selfCastOk == true)
                                break;
                            if (ccs.spellIcon.ManaCost <= MyCreature.Mana && MyCreature.buffManager.IsSilenced() == false && selfCastOk == true)
                                break;
                        }
                        MyCreature.attackSequenceManager.moveNextSequence();
                    }

                    //Run one of the standard AI
                    double runPercent = MyCreature.RunHPPercent / 100.00;
                    if (MyCreature.HP < MyCreature.MaxHP * runPercent)
                        portalTo = RunRetreatAI(MyCreature);
                    else if (MyCreature.attackSequenceManager.CurrentAction is CreatureCastSpell)
                        portalTo = RunSpellCastAI();
                    else if (MyCreature.RangeAttack == true)
                        portalTo = RunRangeWeaponAI(MyCreature);
                    else
                        portalTo = RunDefaultAI(MyCreature);

                    //Set this before the lock ends. Any other methods that are waiting for this lock to open for this character
                    //Will be stopped and re-invoked when this is set to back to false.
                    if (portalTo != null)
                        MyCreature.setIsChangingMaps(true);

                }//End Map Lock

                //Check if we need to portal to another map
                if (portalTo != null)
                {
                    LockItem newLockItem = GameHandler.GetLockItem(portalTo.PortalToMapID, MyCreature.Instance);
                    lock (newLockItem.LockObj)
                    {
                        Map NewMap = GameHandler.GetMap(portalTo.PortalToMapID, MyCreature.Instance);
                        List<Character> CharactersWithin12 = new List<Character>();
                        MapItem PortalToMapItem = null;
                        foreach (MapItem mapitem in NewMap.MapItems)
                        {
                            if (mapitem.MapX == portalTo.PortalToMapX && mapitem.MapY == portalTo.PortalToMapY)
                                PortalToMapItem = mapitem;

                            if (Math.Abs(mapitem.MapX - portalTo.PortalToMapX) <= 12 && Math.Abs(mapitem.MapY - portalTo.PortalToMapY) <= 12)
                            {
                                foreach (CreatureBase creaturebase in mapitem.CreaturesBases)
                                {
                                    if (creaturebase is Character)
                                        CharactersWithin12.Add((Character)creaturebase);
                                }
                            }
                        }

                        MyCreature.SetPosition(PortalToMapItem);
                        PortalToMapItem.CreaturesBases.Add(MyCreature);

                        foreach (Character character in CharactersWithin12)
                        {
                            if (Math.Abs(character.MapX - PortalToMapItem.MapX) <= 8 && Math.Abs(character.MapY - PortalToMapItem.MapY) <= 8)
                                character.AddMapItem(PortalToMapItem);
                        }

                        //Record if portal hex number of creatures
                        numAttackableCreaturesOnStairs = 0;
                        if ((PortalToMapItem.isDark(MyCreature) == false || MyCreature.buffManager.HasNightVision() == true) && (PortalToMapItem.TerrainType == "StairsUp" || PortalToMapItem.TerrainType == "StairsDown"))
                        {
                            foreach (CreatureBase creaturebase in PortalToMapItem.CreaturesBases)
                            {
                                if ((creaturebase.Faction != MyCreature.Faction || MyCreature.hateManager.GetCreatureHateInfo(creaturebase) != null) && creaturebase.HP > 0)
                                    numAttackableCreaturesOnStairs++;
                            }
                        }

                        //Release the map transfer. This will invoke any other methods that got stopped due to the map transfer.
                        MyCreature.setIsChangingMaps(false);

                    }//End Lock

                    //Run Speed
                    Timer_CreatureRound.Interval = 3000;
                    Timer_CreatureRound.Start();
                }
            }// End creatureLock
        }

        //Timer Event Handles Creatures Turn, Does Moves & Attacks, Stops & Fires Respawn timer when creatures are dead
        //public void Timer_CreatureRound_Elapsed(object source, ElapsedEventArgs e)
        //{
        //    MyCreature.currentMapItem.parentMap.addMapJob((Action)runAI, null);
        //}

        private PortalInfo RunDefaultAI(Creature MyCreature)
        {
            Map CurrentMap = GameHandler.GetMap(MyCreature.MapID, MyCreature.Instance);

            //Efficiency issue, we only want to scan the big map once, and we want to run calculations on the smallest possible
            //number of mapitems, so we will need 2 lists, one for move calculations, and one for sounds, pre-image loads
            List<MapItem> CreatureMapItemsWithin4 = new List<MapItem>();
            List<Character> CharactersWithin12 = new List<Character>();
            MapItem CurrentMapItem = MyCreature.currentMapItem;

            //Get Creatures Map
            foreach (MapItem mapitem in MyCreature.currentMapItem.mapItemsWithin12)
            {
                if (Math.Abs(mapitem.MapX - MyCreature.MapX) <= 4 && Math.Abs(mapitem.MapY - MyCreature.MapY) <= 4)
                    CreatureMapItemsWithin4.Add(mapitem);

                if (Math.Abs(mapitem.MapX - MyCreature.MapX) <= 12 && Math.Abs(mapitem.MapY - MyCreature.MapY) <= 12)
                {
                    foreach (CreatureBase creaturebase in mapitem.CreaturesBases)
                    {
                        if (creaturebase is Character)
                            CharactersWithin12.Add((Character)creaturebase);
                    }
                }

                if (mapitem.MapX == MyCreature.MapX && mapitem.MapY == MyCreature.MapY)
                    CurrentMapItem = mapitem;
            }

            //We're looking for creatures so we want to hide dark hexes
            List<Point> hiddenList = FindHidden(MyCreature, CreatureMapItemsWithin4, false);

            //Get a list of all the visible attackable creatures
            List<CreatureBase> attackableCreaturesWithin4 = new List<CreatureBase>();
            foreach (MapItem mapitem in CreatureMapItemsWithin4)
            {
                Point currentPosition = new Point(mapitem.MapX, mapitem.MapY);
                if (isHidden(mapitem.MapX, mapitem.MapY, hiddenList) == false)
                {
                    foreach (CreatureBase creaturebase in mapitem.CreaturesBases)
                    {
                        if (creaturebase.HP > 0 && (creaturebase.Faction != MyCreature.Faction || MyCreature.hateManager.GetCreatureHateInfo(creaturebase) != null) && creaturebase.CanSeeMe(MyCreature))
                            attackableCreaturesWithin4.Add(creaturebase);
                    }
                }
            }
            attackableCreaturesWithin4 = MyCreature.hateManager.prioritizeList(attackableCreaturesWithin4);

            //Reset despawn counter if there are attackable creatures nearby
            if (attackableCreaturesWithin4.Count > 0)
                outOfWanderCounter = 0;

            if (MyCreature.WarmSpell != null && MyCreature.Mana < MyCreature.WarmSpell.ManaCost)
            {
                MyCreature.WarmSpell = null;

                //Play Fizz Sound
                foreach (Character character in CharactersWithin12)
                    character.PlaySound("SpellFizzle", MyCreature.MapX, MyCreature.MapY);
            }

            //Check if we need to move off our current hex
            bool currentHexIsDangerous = hexIsDangerous(MyCreature, CurrentMapItem); ;

            bool creatureToAttackIsOnSameTile = false;

            //Create a list of the attackable creatures on our hex
            List<CreatureBase> CreaturesToAttack = new List<CreatureBase>();
            if (isHidden(CurrentMapItem.MapX, CurrentMapItem.MapY, hiddenList) == false)
            {
                foreach (CreatureBase creaturebase in CurrentMapItem.CreaturesBases)
                {
                    if (creaturebase.HP > 0 && (creaturebase.Faction != MyCreature.Faction || MyCreature.hateManager.GetCreatureHateInfo(creaturebase) != null) && creaturebase.CanSeeMe(MyCreature))
                    {
                        CreaturesToAttack.Add(creaturebase);

                        if (attackableCreaturesWithin4[0] == creaturebase)
                            creatureToAttackIsOnSameTile = true;
                    }
                }
            }
            CreaturesToAttack = MyCreature.hateManager.prioritizeList(CreaturesToAttack);

            //If creature cannot move we dont care if the current hex is dangerous
            if (MyCreature.buffManager.IsRooted() != "" || CurrentMapItem.CreatureMotion() == 0)
                currentHexIsDangerous = false;

            //First thing we are going to check for creatures on our hex to attack for efficiency (we dont need to run any crazy calculations
            //if there are attackable creatures on our hex) Do not stay on hex if damaging AOE Exists
            if ((CurrentMapItem.isDark(MyCreature) == false || MyCreature.buffManager.HasNightVision() == true) && creatureToAttackIsOnSameTile == true && currentHexIsDangerous == false)
            {
                //First sight of enemy, play attack set encounter counter to max
                if (EncounteredCounter == 0)
                {
                    EncounteredCounter = 4;

                    //Play Creature Attack Sound
                    if (MyCreature.SoundEnterCombat != "")
                    {
                        foreach (Character character in CharactersWithin12)
                            character.PlaySound(MyCreature.SoundEnterCombat, MyCreature.MapX, MyCreature.MapY);
                    }
                }

                CreatureBase CharToAttack = attackableCreaturesWithin4[0];

                //Returns true if attack is successfull, false if blocked
                int atkDelay;
                if (MyCreature.AttackCreatureBase(CharactersWithin12, CharToAttack, CreatureMapItemsWithin4, false, out atkDelay) == true)
                {
                    CharToAttack.Update_Character();

                    //Send updates after all attacks are complete
                    if (CharToAttack.HP < 1)
                    {
                        if (!(CharToAttack is Character))
                            CurrentMapItem.CreaturesBases.Remove(CharToAttack);

                        foreach (Character character in CharactersWithin12)
                        {
                            if (Math.Abs(character.MapX - CharToAttack.MapX) <= 4 && Math.Abs(character.MapY - CharToAttack.MapY) <= 4)
                                character.AddMapItem(CurrentMapItem);
                        }
                    }
                    else
                    {
                        foreach (Character character in CharactersWithin12)
                        {
                            if (Math.Abs(character.MapX - CharToAttack.MapX) <= 4 && Math.Abs(character.MapY - CharToAttack.MapY) <= 4)
                                character.UpdateCreatureBaseHp(CharToAttack);
                        }
                    }
                }

                //Record if portal hex and num of creatures
                numAttackableCreaturesOnStairs = 0;
                if ((CurrentMapItem.isDark(MyCreature) == false || MyCreature.buffManager.HasNightVision() == true) && (CurrentMapItem.TerrainType == "StairsUp" || CurrentMapItem.TerrainType == "StairsDown"))
                {
                    foreach (CreatureBase creaturebase in CurrentMapItem.CreaturesBases)
                    {
                        if ((creaturebase.Faction != MyCreature.Faction || MyCreature.hateManager.GetCreatureHateInfo(creaturebase) != null) && creaturebase.HP > 0)
                            numAttackableCreaturesOnStairs++;
                    }
                }

                Timer_CreatureRound.Interval = System.Convert.ToDouble(atkDelay);
                Timer_CreatureRound.Start();
                return null;
            }

            //GET ALL AVAILABLE PATHS
            List<List<MapItem>> Paths = FindAllPaths(MyCreature, CreatureMapItemsWithin4, CurrentMapItem);

            //A count of 1 path, with 1 map item is the map item we're standing on, this means we are stuck due to spell,
            //If there are any creatures on our tile, attack them. otherwise just stand here.

            if (Paths.Count == 1 && Paths[0].Count == 1)
            {
                //We cannot move, so if there is an attackable creature on our tile, attack it.
                if (CreaturesToAttack.Count > 0)
                {
                    CreatureBase CharToAttack = CreaturesToAttack[0];

                    //Returns true if attack is successfull, false if blocked
                    int atkDelay;
                    if (MyCreature.AttackCreatureBase(CharactersWithin12, CharToAttack, CreatureMapItemsWithin4, false, out atkDelay) == true)
                    {
                        CharToAttack.Update_Character();

                        //Send updates after all attacks are complete
                        if (CharToAttack.HP < 1)
                        {
                            if (!(CharToAttack is Character))
                                CurrentMapItem.CreaturesBases.Remove(CharToAttack);

                            foreach (Character character in CharactersWithin12)
                            {
                                if (Math.Abs(character.MapX - CharToAttack.MapX) <= 4 && Math.Abs(character.MapY - CharToAttack.MapY) <= 4)
                                    character.AddMapItem(CurrentMapItem);
                            }
                        }
                        else
                        {
                            foreach (Character character in CharactersWithin12)
                            {
                                if (Math.Abs(character.MapX - CharToAttack.MapX) <= 4 && Math.Abs(character.MapY - CharToAttack.MapY) <= 4)
                                    character.UpdateCreatureBaseHp(CharToAttack);
                            }
                        }
                    }

                    //Record if portal hex and num of creatures
                    numAttackableCreaturesOnStairs = 0;
                    if ((CurrentMapItem.isDark(MyCreature) == false || MyCreature.buffManager.HasNightVision() == true) && (CurrentMapItem.TerrainType == "StairsUp" || CurrentMapItem.TerrainType == "StairsDown"))
                    {
                        foreach (CreatureBase creaturebase in CurrentMapItem.CreaturesBases)
                        {
                            if ((creaturebase.Faction != MyCreature.Faction || MyCreature.hateManager.GetCreatureHateInfo(creaturebase) != null) && creaturebase.HP > 0)
                                numAttackableCreaturesOnStairs++;
                        }
                    }

                    Timer_CreatureRound.Interval = System.Convert.ToDouble(atkDelay);
                    Timer_CreatureRound.Start();
                    return null;
                }
                //We cannot move, so attempt to move our sequence to a castable spell.
                else
                {
                    if (MyCreature.attackSequenceManager.moveToValidSpellAttack() == true)
                    {
                        moveToConjure = false;

                        Timer_CreatureRound.Interval = 3000; 
                        Timer_CreatureRound.Start();
                        return null;
                    }
                }

                Timer_CreatureRound.Interval = 3000;
                Timer_CreatureRound.Start();
                return null;
            }

            List<MapItem> prefferredPath;
            CreatureBase creatureToAttack;
            MyCreature.hateManager.choosePathAndCreatureToAttack(Paths, hiddenList, out prefferredPath, out creatureToAttack);

            if (creatureToAttack != null || attackableCreaturesWithin4.Count > 0)
            {
                //First sight of enemy, play attack set encounter counter to max
                if (EncounteredCounter == 0)
                {
                    //Play Creature Attack Sound
                    if (MyCreature.SoundEnterCombat != "")
                    {
                        foreach (Character character in CharactersWithin12)
                            character.PlaySound(MyCreature.SoundEnterCombat, MyCreature.MapX, MyCreature.MapY);
                    }
                }

                EncounteredCounter = 4;
            }
            else
            {
                if (EncounteredCounter == 0)
                {
                    MyCreature.attackSequenceManager.ResetSequence();
                    if (MyCreature.WarmSpell != null)
                    {
                        MyCreature.WarmSpell = null;
                        foreach (Character ctr in CharactersWithin12)
                            ctr.PlaySound("SpellFizzle", MyCreature.MapX, MyCreature.MapY);
                    }
                }
                else
                    EncounteredCounter--;
            }

            //Cannot find a creature to attack
            if (prefferredPath == null)
            {
                //No visible creatures
                if (attackableCreaturesWithin4.Count == 0)
                {
                    //We didnt find any creatures to attack, so check if the creature ran up or down some stairs to chase it
                    if ((CurrentMapItem.isDark(MyCreature) == false || MyCreature.buffManager.HasNightVision() == true) && (CurrentMapItem.TerrainType == "StairsUp" || CurrentMapItem.TerrainType == "StairsDown"))
                    {
                        if (numAttackableCreaturesOnStairs > 0)
                        {
                            PortalInfo portalInfo = new PortalInfo();
                            portalInfo.PortalToMapID = CurrentMapItem.PortalMapID;
                            portalInfo.PortalToMapX = CurrentMapItem.PortalX;
                            portalInfo.PortalToMapY = CurrentMapItem.PortalY;

                            if (Managers.localWorldsManager.ownsWorld(portalInfo.PortalToMapID, MyCreature.Instance) == true)
                            {
                                CurrentMapItem.CreaturesBases.Remove(MyCreature);

                                foreach (Character character in CharactersWithin12)
                                {
                                    if (Math.Abs(character.MapX - CurrentMapItem.MapX) <= 4 && Math.Abs(character.MapY - CurrentMapItem.MapY) <= 4)
                                        character.AddMapItem(CurrentMapItem);
                                }

                                return portalInfo;
                            }
                        }
                    }
                    
                    return RunWanderAI(CharactersWithin12, CurrentMapItem, CreatureMapItemsWithin4);
                }
                //We have visible creatures
                else
                {
                    //No available magic
                    if (MyCreature.attackSequenceManager.moveToValidSpellAttack() == false || currentHexIsDangerous)
                    {
                        return RunWanderAI(CharactersWithin12, CurrentMapItem, CreatureMapItemsWithin4);
                    }
                    //We have available magic, wait till next round to cast.
                    else
                    {
                        Timer_CreatureRound.Interval = MyCreature.MovementSpeed;
                        Timer_CreatureRound.Start();
                        return null;
                    }
                }
            }

            //Hate manager picked something on our tile.
            else if (prefferredPath != null && prefferredPath.Count == 1 && creatureToAttack != null)
            {
                //Returns true if attack is successfull, false if blocked
                int atkDelay;
                if (MyCreature.AttackCreatureBase(CharactersWithin12, creatureToAttack, CreatureMapItemsWithin4, false, out atkDelay) == true)
                {
                    creatureToAttack.Update_Character();

                    //Send updates after all attacks are complete
                    if (creatureToAttack.HP < 1)
                    {
                        if (!(creatureToAttack is Character))
                            CurrentMapItem.CreaturesBases.Remove(creatureToAttack);

                        foreach (Character character in CharactersWithin12)
                        {
                            if (Math.Abs(character.MapX - creatureToAttack.MapX) <= 4 && Math.Abs(character.MapY - creatureToAttack.MapY) <= 4)
                                character.AddMapItem(CurrentMapItem);
                        }
                    }
                    else
                    {
                        foreach (Character character in CharactersWithin12)
                        {
                            if (Math.Abs(character.MapX - creatureToAttack.MapX) <= 4 && Math.Abs(character.MapY - creatureToAttack.MapY) <= 4)
                                character.UpdateCreatureBaseHp(creatureToAttack);
                        }
                    }
                }

                //Record if portal hex and num of creatures
                numAttackableCreaturesOnStairs = 0;
                if ((CurrentMapItem.isDark(MyCreature) == false || MyCreature.buffManager.HasNightVision() == true) && (CurrentMapItem.TerrainType == "StairsUp" || CurrentMapItem.TerrainType == "StairsDown"))
                {
                    foreach (CreatureBase creaturebase in CurrentMapItem.CreaturesBases)
                    {
                        if ((creaturebase.Faction != MyCreature.Faction || MyCreature.hateManager.GetCreatureHateInfo(creaturebase) != null) && creaturebase.HP > 0)
                            numAttackableCreaturesOnStairs++;
                    }
                }

                Timer_CreatureRound.Interval = System.Convert.ToDouble(atkDelay);
                Timer_CreatureRound.Start();
                return null;
            }
            //Hate manager picked a path either to a creature, or towards a creature
            else
            {
                makeUpdates(MyCreature, prefferredPath, CharactersWithin12, CreatureMapItemsWithin4, creatureToAttack);
                return null;
            }
        }

        private PortalInfo RunRetreatAI(Creature MyCreature)
        {
            Map CurrentMap = GameHandler.GetMap(MyCreature.MapID, MyCreature.Instance);

            //Efficiency issue, we only want to scan the big map once, and we want to run calculations on the smallest possible
            //number of mapitems, so we will need 2 lists, one for move calculations, and one for sounds, pre-image loads
            List<MapItem> CreatureMapItemsWithin4 = new List<MapItem>();
            List<Character> CharactersWithin12 = new List<Character>();
            List<CreatureBase> CreaturesToCastAt = new List<CreatureBase>();
            MapItem CurrentMapItem = MyCreature.currentMapItem;

            //Get Creatures Map
            foreach (MapItem mapitem in MyCreature.currentMapItem.mapItemsWithin12)
            {
                if (Math.Abs(mapitem.MapX - MyCreature.MapX) <= 4 && Math.Abs(mapitem.MapY - MyCreature.MapY) <= 4)
                {
                    CreatureMapItemsWithin4.Add(mapitem);
                    foreach (CreatureBase creaturebase in mapitem.CreaturesBases)
                    {
                        if ((creaturebase.Faction != MyCreature.Faction || MyCreature.hateManager.GetCreatureHateInfo(creaturebase) != null) && creaturebase.HP > 0)
                        {
                            if (creaturebase.CanSeeMe(MyCreature))
                                CreaturesToCastAt.Add(creaturebase);
                        }
                    }
                }

                if (Math.Abs(mapitem.MapX - MyCreature.MapX) <= 12 && Math.Abs(mapitem.MapY - MyCreature.MapY) <= 12)
                {
                    foreach (CreatureBase creaturebase in mapitem.CreaturesBases)
                    {
                        if (creaturebase is Character)
                            CharactersWithin12.Add((Character)creaturebase);
                    }
                }

                if (mapitem.MapX == MyCreature.MapX && mapitem.MapY == MyCreature.MapY)
                    CurrentMapItem = mapitem;
            }

            if (MyCreature.WarmSpell != null)
            {
                MyCreature.WarmSpell = null;

                //Play Fizz Sound
                foreach (Character character in CharactersWithin12)
                    character.PlaySound("SpellFizzle", MyCreature.MapX, MyCreature.MapY);
            }

            //Creature is blind so remove all the creatures to cast at
            if (CurrentMapItem.isDark(MyCreature) == true && MyCreature.buffManager.HasNightVision() == false)
                CreaturesToCastAt.Clear();


            //We're looking for creatures so we want to hide dark hexes
            List<Point> hiddenList = FindHidden(MyCreature, CreatureMapItemsWithin4, false);

            //Remove Creatures from creaturesToCast that are onhidden hexes
            for (int x = 0; x < CreaturesToCastAt.Count; x++)
            {
                foreach (Point point in hiddenList)
                {
                    if (point.X == CreaturesToCastAt[x].MapX && point.Y == CreaturesToCastAt[x].MapY)
                    {
                        CreaturesToCastAt.RemoveAt(x);
                        x--;
                        break;
                    }
                }
            }

            //Creatures are available so we will try to run away, or do melee attack if stuck
            if (CreaturesToCastAt.Count > 0)
            {
                //Reset despawn counter if there are attackable creatures nearby
                outOfWanderCounter = 0;

                //First sight of enemy, play attack set encounter counter to max
                if (EncounteredCounter == 0)
                {
                    //Play Creature Attack Sound
                    if (MyCreature.SoundEnterCombat != "")
                    {
                        foreach (Character character in CharactersWithin12)
                            character.PlaySound(MyCreature.SoundEnterCombat, MyCreature.MapX, MyCreature.MapY);
                    }
                }

                EncounteredCounter = 5;

                //Check if a creature is rooted due to spell or ground effect
                bool noPaths = false;
                if (MyCreature.buffManager.IsRooted() != "" || CurrentMapItem.CreatureMotion() == 0)
                    noPaths = true;

                if (noPaths == false)
                {
                    //GET ALL AVAILABLE PATHS
                    List<List<MapItem>> Paths = FindAllPaths(MyCreature, CreatureMapItemsWithin4, CurrentMapItem, MyCreature.MaxMoves);

                    List<List<MapItem>> PathsWithNoAOE = new List<List<MapItem>>();
                    foreach (List<MapItem> Path in Paths)
                    {
                        for (int x = 1; x < Path.Count; x++)
                        {
                            MapItem mapitem = Path[x];

                            bool isDangerous = hexIsDangerous(MyCreature, mapitem);

                            if (isDangerous == false)
                            {
                                PathsWithNoAOE.Add(Path);
                                break;
                            }
                        }
                    }
                    bool ignoreAOE = false;
                    if (PathsWithNoAOE.Count == 0)
                    {
                        PathsWithNoAOE = Paths;
                        ignoreAOE = true;
                    }

                    int distanceFromCreatures = 0;
                    List<List<MapItem>> PathsAway = new List<List<MapItem>>();
                    for (int x = MyCreature.MaxMoves; x > 0; x--)
                    {
                        foreach (List<MapItem> Path in PathsWithNoAOE)
                        {
                            if (Path.Count > x)
                            {
                                if (ignoreAOE == false && hexIsDangerous(MyCreature, Path[x]))
                                    continue;

                                int distance = 4;
                                foreach (CreatureBase creaturebase in CreaturesToCastAt)
                                {
                                    if (Math.Max(Math.Abs(creaturebase.MapX - Path[x].MapX), Math.Abs(creaturebase.MapY - Path[x].MapY)) < distance)
                                        distance = Math.Max(Math.Abs(creaturebase.MapX - Path[x].MapX), Math.Abs(creaturebase.MapY - Path[x].MapY));

                                }
                                if (distance > distanceFromCreatures)
                                {
                                    distanceFromCreatures = distance;
                                    PathsAway = new List<List<MapItem>>();
                                    PathsAway.Add(Path);
                                }
                                else if (distance == distanceFromCreatures)
                                {
                                    if (PathsAway.Contains(Path) == false)
                                        PathsAway.Add(Path);
                                }
                            }
                        }
                    }

                    //Pick Random out of paths that move away
                    if (PathsAway.Count > 0)
                    {
                        int ChosenPathIndex = GameHandler.random.Next(0, PathsAway.Count);
                        List<MapItem> FullChosenPath = PathsAway[ChosenPathIndex];

                        List<MapItem> ChosenPath = new List<MapItem>();
                        int distanceFromCrits = 0;
                        int distanceToTravel = 0;
                        for (int x = 0; x < FullChosenPath.Count; x++)
                        {
                            int distance = 4;
                            foreach (CreatureBase creaturebase in CreaturesToCastAt)
                            {
                                if (Math.Max(Math.Abs(creaturebase.MapX - FullChosenPath[x].MapX), Math.Abs(creaturebase.MapY - FullChosenPath[x].MapY)) < distance)
                                    distance = Math.Max(Math.Abs(creaturebase.MapX - FullChosenPath[x].MapX), Math.Abs(creaturebase.MapY - FullChosenPath[x].MapY));
                            }
                            if (distance >= distanceFromCrits)
                            {
                                distanceFromCrits = distance;
                                distanceToTravel = x;
                            }
                        }

                        for (int x = 0; x <= distanceToTravel; x++)
                            ChosenPath.Add(FullChosenPath[x]);

                        makeUpdates(MyCreature, ChosenPath, CharactersWithin12, CreatureMapItemsWithin4, null);
                        return null;
                    }

                    Timer_CreatureRound.Interval = 3000;
                    Timer_CreatureRound.Start();
                    return null;
                }

                //TODO: Creatures are around but we cannot move, try for melee or range
                else
                {
                    Timer_CreatureRound.Interval = 3000;
                    Timer_CreatureRound.Start();
                    return null;
                }
            }
            //No creatures are around 
            else
                return RunWanderAI(CharactersWithin12, CurrentMapItem, CreatureMapItemsWithin4);
        }
        private PortalInfo RunRangeWeaponAI(Creature MyCreature)
        {
            Map CurrentMap = GameHandler.GetMap(MyCreature.MapID, MyCreature.Instance);

            //Efficiency issue, we only want to scan the big map once, and we want to run calculations on the smallest possible
            //number of mapitems, so we will need 2 lists, one for move calculations, and one for sounds, pre-image loads
            List<MapItem> CreatureMapItemsWithin4 = new List<MapItem>();
            List<Character> CharactersWithin12 = new List<Character>();
            List<CreatureBase> CreaturesToCastAt = new List<CreatureBase>();
            MapItem CurrentMapItem = MyCreature.currentMapItem;

            //Get Creatures Map
            foreach (MapItem mapitem in MyCreature.currentMapItem.mapItemsWithin12)
            {
                if (Math.Abs(mapitem.MapX - MyCreature.MapX) <= 4 && Math.Abs(mapitem.MapY - MyCreature.MapY) <= 4)
                {
                    CreatureMapItemsWithin4.Add(mapitem);
                    foreach (CreatureBase creaturebase in mapitem.CreaturesBases)
                    {
                        if ((creaturebase.Faction != MyCreature.Faction || MyCreature.hateManager.GetCreatureHateInfo(creaturebase) != null) && creaturebase.HP > 0)
                        {
                            if (creaturebase.CanSeeMe(MyCreature))
                                CreaturesToCastAt.Add(creaturebase);
                        }
                    }
                }

                if (Math.Abs(mapitem.MapX - MyCreature.MapX) <= 12 && Math.Abs(mapitem.MapY - MyCreature.MapY) <= 12)
                {
                    foreach (CreatureBase creaturebase in mapitem.CreaturesBases)
                    {
                        if (creaturebase is Character)
                            CharactersWithin12.Add((Character)creaturebase);
                    }
                }

                if (mapitem.MapX == MyCreature.MapX && mapitem.MapY == MyCreature.MapY)
                    CurrentMapItem = mapitem;
            }

            if (MyCreature.WarmSpell != null)
            {
                MyCreature.WarmSpell = null;

                //Play Fizz Sound
                foreach (Character character in CharactersWithin12)
                    character.PlaySound("SpellFizzle", MyCreature.MapX, MyCreature.MapY);
            }

            //Creature is blind so remove all the creatures to cast at
            if (CurrentMapItem.isDark(MyCreature) == true && MyCreature.buffManager.HasNightVision() == false)
                CreaturesToCastAt.Clear();
            else
            {
                //We're looking for creatures so we want to hide dark hexes
                List<Point> hiddenList = FindHidden(MyCreature, CreatureMapItemsWithin4, false);

                //Remove Creatures from creaturesToCast that are onhidden hexes
                for (int x = 0; x < CreaturesToCastAt.Count; x++)
                {
                    bool moveNext = false;
                    foreach (Point point in hiddenList)
                    {
                        if (point.X == CreaturesToCastAt[x].MapX && point.Y == CreaturesToCastAt[x].MapY)
                        {
                            CreaturesToCastAt.RemoveAt(x);
                            x--;
                            moveNext = true;
                            break;
                        }
                    }

                    if (moveNext == true)
                        continue;
                }
            }

            CreaturesToCastAt = MyCreature.hateManager.prioritizeList(CreaturesToCastAt);

            //We have creatures to attack
            if (CreaturesToCastAt.Count > 0)
            {
                //Reset despawn counter if there are attackable creatures nearby
                outOfWanderCounter = 0;

                //First sight of enemy, play attack set encounter counter to max
                if (EncounteredCounter == 0)
                {
                    EncounteredCounter = 4;

                    //Play Creature Attack Sound
                    if (MyCreature.SoundEnterCombat != "")
                    {
                        foreach (Character character in CharactersWithin12)
                            character.PlaySound(MyCreature.SoundEnterCombat, MyCreature.MapX, MyCreature.MapY);
                    }
                }

                //Even Round
                if (EncounteredCounter % 2 == 0)
                {
                    EncounteredCounter = 5;

                    bool toClose = false;
                    foreach (CreatureBase creaturebase in CreaturesToCastAt)
                    {
                        if (Math.Abs(creaturebase.MapX - MyCreature.MapX) <= 1 && Math.Abs(creaturebase.MapY - MyCreature.MapY) <= 1)
                        {
                            toClose = true;
                            break;
                        }
                    }

                    //Check if a creature is rooted due to spell or ground effect
                    bool noPaths = false;
                    if (MyCreature.buffManager.IsRooted() != "" || CurrentMapItem.CreatureMotion() == 0)
                        noPaths = true;

                    //We're standing on something bad or are to close to creature, move!
                    if ((hexIsDangerous(MyCreature, CurrentMapItem) == true || toClose == true) && noPaths == false)
                    {
                        //GET ALL AVAILABLE PATHS
                        List<List<MapItem>> Paths = FindAllPaths(MyCreature, CreatureMapItemsWithin4, CurrentMapItem, MyCreature.MaxMoves);

                        List<List<MapItem>> PathsWithNoAOE = new List<List<MapItem>>();
                        foreach (List<MapItem> Path in Paths)
                        {
                            for (int x = 1; x < Path.Count; x++)
                            {
                                MapItem mapitem = Path[x];

                                bool isDangerous = hexIsDangerous(MyCreature, mapitem);

                                if (isDangerous == false)
                                {
                                    PathsWithNoAOE.Add(Path);
                                    break;
                                }
                            }
                        }
                        bool ignoreAOE = false;
                        if (PathsWithNoAOE.Count == 0)
                        {
                            PathsWithNoAOE = Paths;
                            ignoreAOE = true;
                        }

                        List<List<MapItem>> PathsAway = new List<List<MapItem>>();
                        int DistanceInPath = 0;
                        for (int x = 1; x <= MyCreature.MaxMoves; x++)
                        {
                            foreach (List<MapItem> Path in PathsWithNoAOE)
                            {
                                if (Path.Count > x)
                                {
                                    bool pathToClose = false;
                                    foreach (CreatureBase creaturebase in CreaturesToCastAt)
                                    {
                                        if (Math.Abs(creaturebase.MapX - Path[x].MapX) <= 1 && Math.Abs(creaturebase.MapY - Path[x].MapY) <= 1)
                                        {
                                            pathToClose = true;
                                            break;
                                        }
                                    }
                                    bool isDangerous = hexIsDangerous(MyCreature, Path[x]);

                                    if (pathToClose == false && (isDangerous == false || ignoreAOE == true))
                                    {
                                        //We check max paths further than we may need to move, so we are going to make sure we dont
                                        //add 2 paths to the same position
                                        bool positionUsed = false;
                                        foreach (List<MapItem> path in PathsAway)
                                        {
                                            if (path[x].MapX == Path[x].MapX && path[x].MapY == Path[x].MapY)
                                            {
                                                positionUsed = true;
                                                break;
                                            }
                                        }
                                        if (positionUsed == false)
                                            PathsAway.Add(Path);
                                    }
                                }
                            }
                            if (PathsAway.Count > 0)
                            {
                                DistanceInPath = x;
                                break;
                            }
                        }

                        //Pick Random out of paths that move away
                        if (PathsAway.Count > 0)
                        {
                            int ChosenPathIndex = GameHandler.random.Next(0, PathsAway.Count);
                            List<MapItem> FullChosenPath = PathsAway[ChosenPathIndex];
                            List<MapItem> ChosenPath = new List<MapItem>();
                            for (int x = 0; x <= DistanceInPath; x++)
                            {
                                ChosenPath.Add(FullChosenPath[x]);
                            }

                            makeUpdates(MyCreature, ChosenPath, CharactersWithin12, CreatureMapItemsWithin4, null);
                        }
                        Timer_CreatureRound.Interval = 3000;
                        Timer_CreatureRound.Start();
                        return null;
                    }
                    //Our current position is not dangerous or to close to creatures
                    else
                    {
                        CreatureBase CharToAttack = CreaturesToCastAt[0];

                        int atkDelay;
                        if (MyCreature.AttackCreatureBase(CharactersWithin12, CharToAttack, CreatureMapItemsWithin4, true, out atkDelay) == true)
                        {
                            CharToAttack.Update_Character();

                            //Send updates after all attacks are complete
                            if (CharToAttack.HP < 1)
                            {
                                MapItem mapitemToUpdate = null;
                                foreach (MapItem m in CreatureMapItemsWithin4)
                                {
                                    if (m.MapX == CharToAttack.MapX && m.MapY == CharToAttack.MapY)
                                    {
                                        mapitemToUpdate = m;
                                        break;
                                    }
                                }

                                if (!(CharToAttack is Character))
                                    mapitemToUpdate.CreaturesBases.Remove(CharToAttack);

                                foreach (Character character in CharactersWithin12)
                                {
                                    if (Math.Abs(character.MapX - CharToAttack.MapX) <= 4 && Math.Abs(character.MapY - CharToAttack.MapY) <= 4)
                                        character.AddMapItem(mapitemToUpdate);
                                }
                            }
                            else
                            {
                                foreach (Character character in CharactersWithin12)
                                {
                                    if (Math.Abs(character.MapX - CharToAttack.MapX) <= 4 && Math.Abs(character.MapY - CharToAttack.MapY) <= 4)
                                        character.UpdateCreatureBaseHp(CharToAttack);
                                }
                            }
                        }

                        Timer_CreatureRound.Interval = atkDelay;
                        Timer_CreatureRound.Start();
                        return null;
                    }
                }
                //Odd Round we attack no matter what (this is to stop perpetual chasing of creature)
                else
                {
                    EncounteredCounter = 4;

                    CreatureBase CharToAttack = CreaturesToCastAt[0];

                    int atkDelay;
                    if (MyCreature.AttackCreatureBase(CharactersWithin12, CharToAttack, CreatureMapItemsWithin4, true, out atkDelay) == true)
                    {
                        CharToAttack.Update_Character();

                        //Send updates after all attacks are complete
                        if (CharToAttack.HP < 1)
                        {
                            MapItem mapitemToUpdate = null;
                            foreach (MapItem m in CreatureMapItemsWithin4)
                            {
                                if (m.MapX == CharToAttack.MapX && m.MapY == CharToAttack.MapY)
                                {
                                    mapitemToUpdate = m;
                                    break;
                                }
                            }

                            if (!(CharToAttack is Character))
                                mapitemToUpdate.CreaturesBases.Remove(CharToAttack);

                            foreach (Character character in CharactersWithin12)
                            {
                                if (Math.Abs(character.MapX - CharToAttack.MapX) <= 4 && Math.Abs(character.MapY - CharToAttack.MapY) <= 4)
                                    character.AddMapItem(mapitemToUpdate);
                            }
                        }
                        else
                        {
                            foreach (Character character in CharactersWithin12)
                            {
                                if (Math.Abs(character.MapX - CharToAttack.MapX) <= 4 && Math.Abs(character.MapY - CharToAttack.MapY) <= 4)
                                    character.UpdateCreatureBaseHp(CharToAttack);
                            }
                        }
                    }

                    Timer_CreatureRound.Interval = atkDelay;
                    Timer_CreatureRound.Start();
                    return null;
                }
            }
            //We have no creatures to attack
            else
                return RunWanderAI(CharactersWithin12, CurrentMapItem, CreatureMapItemsWithin4);
        }

        //This flag is used to determine if our creature got pulled from its specified wander area.
        //Once this flag hits 15, the creature gets moved back to its spawn point.
        private int outOfWanderCounter = 0;
        private PortalInfo RunWanderAI(List<Character> CharactersWithin12, MapItem CurrentMapItem, List<MapItem> CreatureMapItemsWithin4)
        {
            bool fizzle = false;
            if (EncounteredCounter == 0)
            {
                if (MyCreature.WarmSpell != null)
                    fizzle = true;

                MyCreature.attackSequenceManager.ResetSequence();
            }
            else
                EncounteredCounter--;

            if (fizzle == true || (MyCreature.WarmSpell != null && MyCreature.Mana < MyCreature.WarmSpell.ManaCost))
            {
                MyCreature.WarmSpell = null;

                //Play Fizz Sound
                foreach (Character character in CharactersWithin12)
                    character.PlaySound("SpellFizzle", MyCreature.MapX, MyCreature.MapY);
            }

            //GET ALL AVAILABLE PATHS
            int MaxDistance = 2;
            bool currentHexIsDangerous = hexIsDangerous(MyCreature, CurrentMapItem);

            if (currentHexIsDangerous == true)
                MaxDistance = MyCreature.MaxMoves;

            List<List<MapItem>> Paths = FindAllPaths(MyCreature, CreatureMapItemsWithin4, CurrentMapItem, MaxDistance);

            //We have no available paths so do nothing
            if (Paths.Count == 1 && Paths[0].Count == 1)
            {
                Timer_CreatureRound.Interval = 3000;
                Timer_CreatureRound.Start();
                return null;
            }

            List<List<MapItem>> PathsWithNoAOE = new List<List<MapItem>>();

            List<MapItem> ChosenPath = new List<MapItem>();
            if (currentHexIsDangerous == false)
            {
                int DestinationDistance = MaxDistance;
                for (int x = MaxDistance; x >= 0; x--)
                {
                    DestinationDistance = x;
                    foreach (List<MapItem> Path in Paths)
                    {
                        if (Path.Count <= x)
                            continue;

                        if (hexIsDangerous(MyCreature,Path[x]) == false)
                            PathsWithNoAOE.Add(Path);
                    }
                    if (PathsWithNoAOE.Count > 0)
                        break;
                }

                if (PathsWithNoAOE.Count == 0)
                {
                    PathsWithNoAOE = Paths;
                    DestinationDistance = MaxDistance;
                }

                List<List<MapItem>> PathsWithinWander = new List<List<MapItem>>();
                foreach (List<MapItem> Path in PathsWithNoAOE)
                {
                    if (Path.Count <= DestinationDistance)
                        continue;

                    MapItem mapitem = Path[DestinationDistance];

                    if (mapitem.MapX >= MyCreature.WanderMax_W && mapitem.MapX <= MyCreature.WanderMax_E &&
                        mapitem.MapY >= MyCreature.WanderMax_N && mapitem.MapY <= MyCreature.WanderMax_S && 
                        MyCreature.MapID == MyCreature.StartMapID)
                    {
                        PathsWithinWander.Add(Path);
                    }
                }

                if (PathsWithinWander.Count > 0 ||
                    (MyCreature.WanderMax_E == -1 && MyCreature.WanderMax_N == -1 && MyCreature.WanderMax_S == -1 && MyCreature.WanderMax_W == -1 && MyCreature.MapID == MyCreature.StartMapID))
                {
                    outOfWanderCounter = 0;
                }
                else
                    outOfWanderCounter++;

                if (PathsWithinWander.Count > 0)
                    PathsWithNoAOE = PathsWithinWander;

                int ChosenPathIndex = GameHandler.random.Next(0, PathsWithNoAOE.Count);

                for (int x = 0; x <= DestinationDistance; x++)
                    ChosenPath.Add(PathsWithNoAOE[ChosenPathIndex][x]);
            }
            else
            {
                outOfWanderCounter = 0;

                List<List<MapItem>> PathsSafe = new List<List<MapItem>>();
                int DistanceToSafe = 0;
                for (int x = 0; x <= MyCreature.MaxMoves; x++)
                {
                    foreach (List<MapItem> path in Paths)
                    {
                        if (path.Count <= x)
                            continue;

                        MapItem mapitem = path[x];
                        bool isDangerous = hexIsDangerous(MyCreature, mapitem);

                        if (isDangerous == false)
                        {
                            PathsSafe.Add(path);
                        }
                    }
                    if (PathsSafe.Count > 0)
                    {
                        DistanceToSafe = x;
                        break;
                    }
                }
                if (PathsSafe.Count > 0)
                {
                    List<MapItem> FullChosenPath = PathsSafe[GameHandler.random.Next(PathsSafe.Count)];
                    for (int y = 0; y <= DistanceToSafe; y++)
                    {
                        ChosenPath.Add(FullChosenPath[y]);
                    }
                }
                else
                {
                    ChosenPath = Paths[GameHandler.random.Next(Paths.Count)];
                }
            }

            //Despawn creature, its been wandering around outside of its area for 15 rounds.
            if (outOfWanderCounter >= 40)
            {
                //Remove Creature from its current map item.
                CurrentMapItem.CreaturesBases.Remove(MyCreature);

                //Dummy list to update nearby characters
                List<MapItem> mapItemsToUpdate = new List<MapItem>();
                mapItemsToUpdate.Add(CurrentMapItem);

                //Update nearby characters
                foreach (Character charToUpdate in CharactersWithin12)
                {
                    if (Math.Abs(charToUpdate.MapX - CurrentMapItem.MapX) <= 4 && Math.Abs(charToUpdate.MapY - CurrentMapItem.MapY) <= 4)
                        charToUpdate.AddMapItems(mapItemsToUpdate, false);
                }

                PortalInfo pi = new PortalInfo();
                pi.PortalToMapID = MyCreature.StartMapID;
                pi.PortalToMapX = MyCreature.StartMapX;
                pi.PortalToMapY = MyCreature.StartMapY;

                outOfWanderCounter = 0;

                return pi;
            }
            else
                makeUpdates(MyCreature, ChosenPath, CharactersWithin12, CreatureMapItemsWithin4, null);

            return null;
        }

        //Flag used to make the casters only move away every other conjure
        private bool moveToConjure = true;
        private PortalInfo RunSpellCastAI()
        {
            //Debugging
            //if (MyCreature.ID == 355)
            //{
            //    int xxx = 0;
            //}

            CreatureCastSpell creatureCastSpell = (CreatureCastSpell)MyCreature.attackSequenceManager.CurrentAction;

            Map CurrentMap = GameHandler.GetMap(MyCreature.MapID, MyCreature.Instance);

            //Efficiency issue, we only want to scan the big map once, and we want to run calculations on the smallest possible
            //number of mapitems, so we will need 2 lists, one for move calculations, and one for sounds, pre-image loads
            List<MapItem> CreatureMapItemsWithin4 = new List<MapItem>();
            List<Character> CharactersWithin12 = new List<Character>();
            
            //Hostile Creatures
            List<CreatureBase> CreaturesToCastAt = new List<CreatureBase>();
            MapItem CurrentMapItem = MyCreature.currentMapItem;

            //Get Creatures Map
            foreach (MapItem mapitem in MyCreature.currentMapItem.mapItemsWithin12)
            {
                if (Math.Abs(mapitem.MapX - MyCreature.MapX) <= 4 && Math.Abs(mapitem.MapY - MyCreature.MapY) <= 4)
                {
                    CreatureMapItemsWithin4.Add(mapitem);
                    foreach (CreatureBase creaturebase in mapitem.CreaturesBases)
                    {
                        if ((creaturebase.Faction != MyCreature.Faction || MyCreature.hateManager.GetCreatureHateInfo(creaturebase) != null) && creaturebase.HP > 0)
                        {
                            if (creaturebase.CanSeeMe(MyCreature))
                                CreaturesToCastAt.Add(creaturebase);
                        }
                    }
                }

                if (Math.Abs(mapitem.MapX - MyCreature.MapX) <= 12 && Math.Abs(mapitem.MapY - MyCreature.MapY) <= 12)
                {
                    foreach (CreatureBase creaturebase in mapitem.CreaturesBases)
                    {
                        if (creaturebase is Character)
                            CharactersWithin12.Add((Character)creaturebase);
                    }
                }

                if (mapitem.MapX == MyCreature.MapX && mapitem.MapY == MyCreature.MapY)
                    CurrentMapItem = mapitem;
            }

            //Check if spell has custom target, and if is available
            //Cast Warmed Spell
            Assembly assembly = Assembly.GetExecutingAssembly();
            string fullTypeName = "Reborn_Server.App1AppHandler" + "." + creatureCastSpell.spellIcon.ClassName;
            Type myType = assembly.GetType(fullTypeName);
            object ClassObj = Activator.CreateInstance(myType);

            Object[] args = { creatureCastSpell.spellIcon };
            bool spellHasCustomTarget = System.Convert.ToBoolean(myType.InvokeMember("hasCustomTarget", BindingFlags.Default | BindingFlags.InvokeMethod, null, ClassObj, args));
            bool spellHasValidTarget = true;


            bool spellCastAlone = System.Convert.ToBoolean(myType.InvokeMember("castWhileAlone", BindingFlags.Default | BindingFlags.InvokeMethod, null, ClassObj, args));

            //Creature is blind so remove all the creatures to cast at
            if (CurrentMapItem.isDark(MyCreature) == true && MyCreature.buffManager.HasNightVision() == false)
            {
                CreaturesToCastAt.Clear();
                spellHasValidTarget = false;
            }
            //Remove creatures that are hidden from view
            else
            {
                //We're looking for creatures so we want to hide dark hexes
                List<Point> hiddenList = FindHidden(MyCreature, CreatureMapItemsWithin4, false);

                if (spellHasCustomTarget == true)
                {
                    Object[] args2 = { creatureCastSpell.spellIcon, MyCreature, hiddenList };
                    spellHasValidTarget = System.Convert.ToBoolean(myType.InvokeMember("hasValidTarget", BindingFlags.Default | BindingFlags.InvokeMethod, null, ClassObj, args2));
                }           

                //Remove Creatures from creaturesToCast that are onhidden hexes
                for (int x = 0; x < CreaturesToCastAt.Count; x++)
                {
                    bool moveNext = false;
                    foreach (Point point in hiddenList)
                    {
                        if (point.X == CreaturesToCastAt[x].MapX && point.Y == CreaturesToCastAt[x].MapY)
                        {
                            CreaturesToCastAt.RemoveAt(x);
                            x--;
                            moveNext = true;
                            break;
                        }
                    }

                    if (moveNext == true)
                        continue;
                }
            }

            CreaturesToCastAt = MyCreature.hateManager.prioritizeList(CreaturesToCastAt);

            //Reset despawn counter if there are attackable creatures nearby
            if (CreaturesToCastAt.Count > 0)
                outOfWanderCounter = 0;

            //We have creatures to attack
            if ((CreaturesToCastAt.Count > 0 || spellCastAlone) && spellHasValidTarget == true)
            {
                EncounteredCounter = 4;
                //Creature does not have spell warmed
                if (MyCreature.WarmSpell == null && creatureCastSpell.Instant == false)
                {
                    bool toClose = false;
                    foreach (CreatureBase creaturebase in CreaturesToCastAt)
                    {
                        if (Math.Abs(creaturebase.MapX - MyCreature.MapX) <= 1 && Math.Abs(creaturebase.MapY - MyCreature.MapY) <= 1)
                        {
                            toClose = true;
                            break;
                        }
                    }

                    bool currentHexIsDangerous = hexIsDangerous(MyCreature, CurrentMapItem);

                    //We have no available paths so just pretend there are no creatures nearby and current hex is not dangerous
                    if (MyCreature.buffManager.IsRooted() != "" || CurrentMapItem.CreatureMotion() == 0)
                    {
                        currentHexIsDangerous = false;
                        toClose = false;
                    }

                    //Trying to conjure a self cast spell, we dont care how far away from enemies we are
                    if (creatureCastSpell.spellIcon.CastType == "Self")
                        toClose = false;

                    //Forces the creatures to alternate running away and casting, otherwise they will get stuck continually running
                    //from things like pets.
                    if (toClose == true && moveToConjure == false)
                    {
                        toClose = false;
                        moveToConjure = true;
                    }

                    //Creature is far enough from targets, warm the spell
                    if (toClose == false && currentHexIsDangerous == false)
                    {
                        CreatureCastSpell ccs = (CreatureCastSpell)MyCreature.attackSequenceManager.CurrentAction;

                        MyCreature.WarmSpell = ccs.spellIcon;
                        WarmSpellLevel = ccs.SkillLevel;

                        Message msg = new Message();
                        msg.CreatureID = -1;
                        msg.Type = "spelloffense";
                        msg.Text = MyCreature.Name + " begins conjuring a spell";

                        MyCreature.MessageBroadcast(CreatureMapItemsWithin4, msg, false);

                        //Play Warm spell sound & send conjure message
                        foreach (Character character in CharactersWithin12)
                        {
                            if (Math.Abs(character.MapX - MyCreature.MapX) <= 8 && Math.Abs(character.MapY - MyCreature.MapY) <= 8)
                                character.PlaySound("SpellConjure", MyCreature.MapX, MyCreature.MapY);
                        }

                        Timer_CreatureRound.Interval = 3000 + (3000.00 * (MyCreature.CastingSpeedPercentModifier / 100.00));
                        Timer_CreatureRound.Start();
                        return null;
                    }
                    //Creature is to close to targets, move away
                    else
                    {
                        if (moveToConjure == true && toClose == true)
                            moveToConjure = false;

                        //GET ALL AVAILABLE PATHS
                        List<List<MapItem>> Paths = FindAllPaths(MyCreature, CreatureMapItemsWithin4, CurrentMapItem, MyCreature.MaxMoves);

                        List<List<MapItem>> PathsWithNoAOE = new List<List<MapItem>>();
                        foreach (List<MapItem> Path in Paths)
                        {
                            for (int x = 1; x < Path.Count; x++)
                            {
                                MapItem mapitem = Path[x];

                                bool isDangerous = hexIsDangerous(MyCreature, mapitem);

                                if (isDangerous == false)
                                {
                                    PathsWithNoAOE.Add(Path);
                                    break;
                                }
                            }
                        }
                        bool ignoreAOE = false;
                        if (PathsWithNoAOE.Count == 0)
                        {
                            PathsWithNoAOE = Paths;
                            ignoreAOE = true;
                        }

                        List<List<MapItem>> PathsAway = new List<List<MapItem>>();
                        int DistanceInPath = 0;
                        for (int x = 1; x <= MyCreature.MaxMoves; x++)
                        {
                            foreach (List<MapItem> Path in PathsWithNoAOE)
                            {
                                if (Path.Count > x)
                                {
                                    bool pathToClose = false;
                                    foreach (CreatureBase creaturebase in CreaturesToCastAt)
                                    {
                                        if (Math.Abs(creaturebase.MapX - Path[x].MapX) <= 1 && Math.Abs(creaturebase.MapY - Path[x].MapY) <= 1)
                                        {
                                            pathToClose = true;
                                            break;
                                        }
                                    }
                                    bool isDangerous = hexIsDangerous(MyCreature, Path[x]);

                                    if (pathToClose == false && (isDangerous == false || ignoreAOE == true))
                                    {
                                        //We check max paths further than we may need to move, so we are going to make sure we dont
                                        //add 2 paths to the same position
                                        bool positionUsed = false;
                                        foreach (List<MapItem> path in PathsAway)
                                        {
                                            if (path[x].MapX == Path[x].MapX && path[x].MapY == Path[x].MapY)
                                            {
                                                positionUsed = true;
                                                break;
                                            }
                                        }
                                        if (positionUsed == false)
                                            PathsAway.Add(Path);
                                    }
                                }
                            }
                            if (PathsAway.Count > 0)
                            {
                                DistanceInPath = x;
                                break;
                            }
                        }

                        //Pick Random out of paths that move away
                        if (PathsAway.Count > 0)
                        {
                            int ChosenPathIndex = GameHandler.random.Next(0, PathsAway.Count);
                            List<MapItem> FullChosenPath = PathsAway[ChosenPathIndex];
                            List<MapItem> ChosenPath = new List<MapItem>();
                            for (int x = 0; x <= DistanceInPath; x++)
                            {
                                ChosenPath.Add(FullChosenPath[x]);
                            }

                            makeUpdates(MyCreature, ChosenPath, CharactersWithin12, CreatureMapItemsWithin4, null);
                        }
                        Timer_CreatureRound.Interval = 3000 + (3000.00 * (MyCreature.CastingSpeedPercentModifier / 100.00));
                        Timer_CreatureRound.Start();
                        return null;
                    }
                }
                //Creature Has spell warmed or is instant cast
                else
                {
                    SpellIcon spellIconToCast = null;
                    if (MyCreature.WarmSpell != null)
                        spellIconToCast = MyCreature.WarmSpell;
                    else
                        spellIconToCast = creatureCastSpell.spellIcon;

                    //Area spell is warmed so we dont want to kill allies
                    if (spellIconToCast.CastType == "Area")
                    {
                        List<CreatureBase> AttackCreaturesSafeFromAllies = new List<CreatureBase>();
                        foreach (CreatureBase creaturebase in CreaturesToCastAt)
                        {
                            int numberOfAllies = 0;
                            foreach (MapItem mapitem in CreatureMapItemsWithin4)
                            {
                                if (Math.Abs(mapitem.MapX - creaturebase.MapX) <= spellIconToCast.AreaRadius && Math.Abs(mapitem.MapY - creaturebase.MapY) <= spellIconToCast.AreaRadius)
                                {
                                    foreach (CreatureBase cb in mapitem.CreaturesBases)
                                    {
                                        if (cb.Faction == MyCreature.Faction)
                                        {
                                            numberOfAllies++;
                                        }
                                    }
                                }
                            }
                            if (numberOfAllies < creatureCastSpell.allowAllyAttackCount || creatureCastSpell.allowAllyAttackCount == -1)
                                AttackCreaturesSafeFromAllies.Add(creaturebase);
                        }
                        //Safe to cast (not enough allies will die to worry)
                        if (AttackCreaturesSafeFromAllies.Count > 0)
                        {
                            AttackCreaturesSafeFromAllies = MyCreature.hateManager.prioritizeList(AttackCreaturesSafeFromAllies);
                            CreatureBase AttackCreature = AttackCreaturesSafeFromAllies[0];

                            //Its a warmed spell
                            if (MyCreature.WarmSpell != null)
                            {
                                //Cast Warmed Spell
                                //Assembly assembly = Assembly.GetExecutingAssembly();
                                //string fullTypeName = "Reborn_Server.App1AppHandler" + "." + spellIconToCast.ClassName;
                                //Type myType = assembly.GetType(fullTypeName);

                                //object ClassObj = Activator.CreateInstance(myType);

                                Object[] args3 = { spellIconToCast, MyCreature, creatureCastSpell.SkillLevel, AttackCreature.MapX, AttackCreature.MapY };
                                object Result = myType.InvokeMember("CreatureCast", BindingFlags.Default | BindingFlags.InvokeMethod, null, ClassObj, args3);
                            }
                            //Its an instant cast
                            else
                            {
                                //Assembly assembly = Assembly.GetExecutingAssembly();
                                //string fullTypeName = "Reborn_Server.App1AppHandler" + "." + spellIconToCast.ClassName;
                                //Type myType = assembly.GetType(fullTypeName);

                                //object ClassObj = Activator.CreateInstance(myType);

                                Object[] args4 = { spellIconToCast, MyCreature, creatureCastSpell.SkillLevel, AttackCreature.MapX, AttackCreature.MapY };
                                object Result = myType.InvokeMember("PositionCast", BindingFlags.Default | BindingFlags.InvokeMethod, null, ClassObj, args4);
                            }
                            
                            //We should not need this, but incase the spell cast fails, we dont want a warm spell when we change sequence
                            MyCreature.WarmSpell = null;

                            MyCreature.attackSequenceManager.moveNextSequence();
                        }
                        //Not safe to cast, so check if we need to move further away since we're not going to cast
                        else
                        {
                            bool toClose = false;
                            foreach (CreatureBase creaturebase in CreaturesToCastAt)
                            {
                                if (Math.Abs(creaturebase.MapX - MyCreature.MapX) <= 1 && Math.Abs(creaturebase.MapY - MyCreature.MapY) <= 1)
                                {
                                    toClose = true;
                                    break;
                                }
                            }

                            //GET ALL AVAILABLE PATHS
                            List<List<MapItem>> Paths = FindAllPaths(MyCreature, CreatureMapItemsWithin4, CurrentMapItem, MyCreature.MaxMoves);

                            //We have no available paths to pretend there are no nearby creatures
                            if (Paths.Count == 1 && Paths[0].Count == 1)
                                toClose = false;

                            //Creature is to close to targets, move away
                            if (toClose == true || hexIsDangerous(MyCreature, CurrentMapItem))
                            {
                                List<List<MapItem>> PathsWithNoAOE = new List<List<MapItem>>();
                                foreach (List<MapItem> Path in Paths)
                                {
                                    for (int x = 1; x < Path.Count; x++)
                                    {
                                        MapItem mapitem = Path[x];

                                        bool isDangerous = hexIsDangerous(MyCreature, mapitem);

                                        if (isDangerous == false)
                                        {
                                            PathsWithNoAOE.Add(Path);
                                            break;
                                        }
                                    }
                                }
                                bool ignoreAOE = false;
                                if (PathsWithNoAOE.Count == 0)
                                {
                                    PathsWithNoAOE = Paths;
                                    ignoreAOE = true;
                                }

                                List<List<MapItem>> PathsAway = new List<List<MapItem>>();
                                int DistanceInPath = 0;
                                for (int x = 1; x <= MyCreature.MaxMoves; x++)
                                {
                                    foreach (List<MapItem> Path in PathsWithNoAOE)
                                    {
                                        if (Path.Count > x)
                                        {
                                            bool pathToClose = false;
                                            foreach (CreatureBase creaturebase in CreaturesToCastAt)
                                            {
                                                if (Math.Abs(creaturebase.MapX - Path[x].MapX) <= 1 && Math.Abs(creaturebase.MapY - Path[x].MapY) <= 1)
                                                {
                                                    pathToClose = true;
                                                    break;
                                                }
                                            }
                                            bool isDangerous = hexIsDangerous(MyCreature, Path[x]);

                                            if (pathToClose == false && (isDangerous == false || ignoreAOE == true))
                                            {
                                                //We check max paths further than we may need to move, so we are going to make sure we dont
                                                //add 2 paths to the same position
                                                bool positionUsed = false;
                                                foreach (List<MapItem> path in PathsAway)
                                                {
                                                    if (path[x].MapX == Path[x].MapX && path[x].MapY == Path[x].MapY)
                                                    {
                                                        positionUsed = true;
                                                        break;
                                                    }
                                                }
                                                if (positionUsed == false)
                                                    PathsAway.Add(Path);
                                            }
                                        }
                                    }
                                    if (PathsAway.Count > 0)
                                    {
                                        DistanceInPath = x;
                                        break;
                                    }
                                }

                                //Pick Random out of paths that move away
                                if (PathsAway.Count > 0)
                                {
                                    int ChosenPathIndex = GameHandler.random.Next(0, PathsAway.Count);
                                    List<MapItem> FullChosenPath = PathsAway[ChosenPathIndex];
                                    List<MapItem> ChosenPath = new List<MapItem>();
                                    for (int x = 0; x <= DistanceInPath; x++)
                                    {
                                        ChosenPath.Add(FullChosenPath[x]);
                                    }

                                    makeUpdates(MyCreature, ChosenPath, CharactersWithin12, CreatureMapItemsWithin4, null);
                                    return null;
                                }
                            }
                        }
                        Timer_CreatureRound.Interval = 3000 + (3000.00 * (MyCreature.CastingSpeedPercentModifier / 100.00));
                        Timer_CreatureRound.Start();
                        return null;
                    }
                    //Spell is not an area spell, just cast it
                    else
                    {
                        CreatureBase critToCastAt = null;
                        if (creatureCastSpell.spellIcon.CastType == "Self")
                            critToCastAt = MyCreature;
                        else if (CreaturesToCastAt.Count > 0)
                            critToCastAt = CreaturesToCastAt[0];

                        //Assembly assembly = Assembly.GetExecutingAssembly();
                        //string fullTypeName = "Reborn_Server.App1AppHandler" + "." + creatureCastSpell.spellIcon.ClassName;
                        //Type myType = assembly.GetType(fullTypeName);

                        //object ClassObj = Activator.CreateInstance(myType);

                        if (creatureCastSpell.Instant == false)
                        {
                            long creatureIdToUse = -1;
                            if (critToCastAt != null)
                                creatureIdToUse = critToCastAt.CreatureID;

                            Object[] args5 = { MyCreature, WarmSpellLevel, creatureIdToUse };
                            object Result = myType.InvokeMember("Cast", BindingFlags.Default | BindingFlags.InvokeMethod, null, ClassObj, args5);
                        }
                        else 
                        {
                            IInstantCast spellToCast = (IInstantCast)ClassObj;
                            spellToCast.InstantCast(MyCreature, critToCastAt, creatureCastSpell.spellIcon, creatureCastSpell.SkillLevel);
                            
                            //Object[] args6 = {MyCreature, critToCastAt, creatureCastSpell.spellIcon, creatureCastSpell.SkillLevel};

                            //public void InstantCast(CreatureBase targetCreatureBase, int CastingCharacterID, SpellIcon _spellIcon, int castLevel, int castInt, int castWis)
                            //object Result = myType.InvokeMember("InstantCast", BindingFlags.Default | BindingFlags.InvokeMethod, null, ClassObj, args6);
                        }

                        //We should not need this, but incase the spell cast fails, we dont want a warm spell when we change sequence
                        MyCreature.WarmSpell = null;

                        Timer_CreatureRound.Interval = 1550; // +(1500.00 * (MyCreature.CastingSpeedPercentModifier / 100.00));
                        Timer_CreatureRound.Start();

                        MyCreature.attackSequenceManager.moveNextSequence();

                        return null;
                    }
                }
            }
            //Enemies around, but our spell is invalid (like a heal when there is no creatures damaged)
            else if (CreaturesToCastAt.Count > 0 && spellHasValidTarget == false)
            {
                MyCreature.attackSequenceManager.moveNextSequence();

                if (MyCreature.WarmSpell != null)
                    MyCreature.WarmSpell = null;

                runAI();
                return null;
            }
            //We have no creatures to attack
            else
                return RunWanderAI(CharactersWithin12, CurrentMapItem, CreatureMapItemsWithin4);
        }

        //Helper function: Gets the next positions to check for pathing per our movement direction (Also prioritizes)
        private static List<Point> positionsToCheck(Point CurrentPosition, Point? LastPosition)
        {
            List<Point> Positions = new List<Point>();
            Point PathOption;

            if (LastPosition != null)
            {
                //W
                if (CurrentPosition.X - LastPosition.Value.X == -1 && CurrentPosition.Y - LastPosition.Value.Y == 0)
                {
                    //W
                    PathOption = new Point(CurrentPosition.X - 1, CurrentPosition.Y + 0);
                    Positions.Add(PathOption);
                    //NW
                    PathOption = new Point(CurrentPosition.X - 1, CurrentPosition.Y - 1);
                    Positions.Add(PathOption);
                    //SW
                    PathOption = new Point(CurrentPosition.X - 1, CurrentPosition.Y + 1);
                    Positions.Add(PathOption);

                    //N
                    PathOption = new Point(CurrentPosition.X - 0, CurrentPosition.Y - 1);
                    Positions.Add(PathOption);
                    //S
                    PathOption = new Point(CurrentPosition.X - 0, CurrentPosition.Y + 1);
                    Positions.Add(PathOption);

                }
                //NW
                else if (CurrentPosition.X - LastPosition.Value.X == -1 && CurrentPosition.Y - LastPosition.Value.Y == -1)
                {
                    //NW
                    PathOption = new Point(CurrentPosition.X - 1, CurrentPosition.Y - 1);
                    Positions.Add(PathOption);
                    //N
                    PathOption = new Point(CurrentPosition.X - 0, CurrentPosition.Y - 1);
                    Positions.Add(PathOption);
                    //W
                    PathOption = new Point(CurrentPosition.X - 1, CurrentPosition.Y + 0);
                    Positions.Add(PathOption);

                    //NE
                    PathOption = new Point(CurrentPosition.X + 1, CurrentPosition.Y - 1);
                    Positions.Add(PathOption);
                    //SW
                    PathOption = new Point(CurrentPosition.X - 1, CurrentPosition.Y + 1);
                    Positions.Add(PathOption);

                }
                //N
                else if (CurrentPosition.X - LastPosition.Value.X == 0 && CurrentPosition.Y - LastPosition.Value.Y == -1)
                {
                    //N
                    PathOption = new Point(CurrentPosition.X - 0, CurrentPosition.Y - 1);
                    Positions.Add(PathOption);
                    //NE
                    PathOption = new Point(CurrentPosition.X + 1, CurrentPosition.Y - 1);
                    Positions.Add(PathOption);
                    //NW
                    PathOption = new Point(CurrentPosition.X - 1, CurrentPosition.Y - 1);
                    Positions.Add(PathOption);

                    //E
                    PathOption = new Point(CurrentPosition.X + 1, CurrentPosition.Y + 0);
                    Positions.Add(PathOption);
                    //W
                    PathOption = new Point(CurrentPosition.X - 1, CurrentPosition.Y + 0);
                    Positions.Add(PathOption);

                }
                //NE
                else if (CurrentPosition.X - LastPosition.Value.X == 1 && CurrentPosition.Y - LastPosition.Value.Y == -1)
                {
                    //NE
                    PathOption = new Point(CurrentPosition.X + 1, CurrentPosition.Y - 1);
                    Positions.Add(PathOption);
                    //N
                    PathOption = new Point(CurrentPosition.X - 0, CurrentPosition.Y - 1);
                    Positions.Add(PathOption);
                    //E
                    PathOption = new Point(CurrentPosition.X + 1, CurrentPosition.Y + 0);
                    Positions.Add(PathOption);

                    //SE
                    PathOption = new Point(CurrentPosition.X + 1, CurrentPosition.Y + 1);
                    Positions.Add(PathOption);
                    //NW
                    PathOption = new Point(CurrentPosition.X - 1, CurrentPosition.Y - 1);
                    Positions.Add(PathOption);

                }
                //E
                else if (CurrentPosition.X - LastPosition.Value.X == 1 && CurrentPosition.Y - LastPosition.Value.Y == 0)
                {
                    //E
                    PathOption = new Point(CurrentPosition.X + 1, CurrentPosition.Y + 0);
                    Positions.Add(PathOption);
                    //NE
                    PathOption = new Point(CurrentPosition.X + 1, CurrentPosition.Y - 1);
                    Positions.Add(PathOption);
                    //SE
                    PathOption = new Point(CurrentPosition.X + 1, CurrentPosition.Y + 1);
                    Positions.Add(PathOption);

                    //N
                    PathOption = new Point(CurrentPosition.X - 0, CurrentPosition.Y - 1);
                    Positions.Add(PathOption);
                    //S
                    PathOption = new Point(CurrentPosition.X - 0, CurrentPosition.Y + 1);
                    Positions.Add(PathOption);
                }
                //SE
                else if (CurrentPosition.X - LastPosition.Value.X == 1 && CurrentPosition.Y - LastPosition.Value.Y == 1)
                {
                    //SE
                    PathOption = new Point(CurrentPosition.X + 1, CurrentPosition.Y + 1);
                    Positions.Add(PathOption);
                    //E
                    PathOption = new Point(CurrentPosition.X + 1, CurrentPosition.Y + 0);
                    Positions.Add(PathOption);
                    //S
                    PathOption = new Point(CurrentPosition.X - 0, CurrentPosition.Y + 1);
                    Positions.Add(PathOption);

                    //NE
                    PathOption = new Point(CurrentPosition.X + 1, CurrentPosition.Y - 1);
                    Positions.Add(PathOption);
                    //SW
                    PathOption = new Point(CurrentPosition.X - 1, CurrentPosition.Y + 1);
                    Positions.Add(PathOption);
                }
                //S
                else if (CurrentPosition.X - LastPosition.Value.X == 0 && CurrentPosition.Y - LastPosition.Value.Y == 1)
                {
                    //S
                    PathOption = new Point(CurrentPosition.X - 0, CurrentPosition.Y + 1);
                    Positions.Add(PathOption);
                    //SE
                    PathOption = new Point(CurrentPosition.X + 1, CurrentPosition.Y + 1);
                    Positions.Add(PathOption);
                    //SW
                    PathOption = new Point(CurrentPosition.X - 1, CurrentPosition.Y + 1);
                    Positions.Add(PathOption);

                    //E
                    PathOption = new Point(CurrentPosition.X + 1, CurrentPosition.Y + 0);
                    Positions.Add(PathOption);
                    //W
                    PathOption = new Point(CurrentPosition.X - 1, CurrentPosition.Y + 0);
                    Positions.Add(PathOption);

                }
                //SW
                else if (CurrentPosition.X - LastPosition.Value.X == -1 && CurrentPosition.Y - LastPosition.Value.Y == 1)
                {
                    //SW
                    PathOption = new Point(CurrentPosition.X - 1, CurrentPosition.Y + 1);
                    Positions.Add(PathOption);
                    //S
                    PathOption = new Point(CurrentPosition.X - 0, CurrentPosition.Y + 1);
                    Positions.Add(PathOption);
                    //W
                    PathOption = new Point(CurrentPosition.X - 1, CurrentPosition.Y + 0);
                    Positions.Add(PathOption);

                    //SE
                    PathOption = new Point(CurrentPosition.X + 1, CurrentPosition.Y + 1);
                    Positions.Add(PathOption);
                    //NW
                    PathOption = new Point(CurrentPosition.X - 1, CurrentPosition.Y - 1);
                    Positions.Add(PathOption);
                }
            }
            //First Move, we have no direction
            else
            {
                //NW
                PathOption = new Point(CurrentPosition.X - 1, CurrentPosition.Y - 1);
                Positions.Add(PathOption);
                //N
                PathOption = new Point(CurrentPosition.X - 0, CurrentPosition.Y - 1);
                Positions.Add(PathOption);
                //NE
                PathOption = new Point(CurrentPosition.X + 1, CurrentPosition.Y - 1);
                Positions.Add(PathOption);
                //E
                PathOption = new Point(CurrentPosition.X + 1, CurrentPosition.Y + 0);
                Positions.Add(PathOption);
                //SE
                PathOption = new Point(CurrentPosition.X + 1, CurrentPosition.Y + 1);
                Positions.Add(PathOption);
                //S
                PathOption = new Point(CurrentPosition.X - 0, CurrentPosition.Y + 1);
                Positions.Add(PathOption);
                //SW
                PathOption = new Point(CurrentPosition.X - 1, CurrentPosition.Y + 1);
                Positions.Add(PathOption);
                //W
                PathOption = new Point(CurrentPosition.X - 1, CurrentPosition.Y + 0);
                Positions.Add(PathOption);
            }

            return Positions;
        }

        //Helper function: Deterimines if a hex is considered dangerous to a creature
        static public bool hexIsDangerous(Creature creature, MapItem mapitem)
        {
            foreach (Spell spell in mapitem.SpellLayer0)
            {
                if (spell is AreaSpell)
                {
                    AreaSpell areaSpell = (AreaSpell)spell;
                    if (areaSpell.isDangerous(creature) == true)
                        return true;
                }
            }
            foreach (Spell spell in mapitem.SpellLayer1)
            {
                if (spell is AreaSpell)
                {
                    AreaSpell areaSpell = (AreaSpell)spell;
                    if (areaSpell.isDangerous(creature) == true)
                        return true;
                }
            }
            return false;
        }

        //Helper function: Modifies map and sends updates after creature chooses path
        private void makeUpdates(Creature MyCreature, List<MapItem> ChosenPath, List<Character> CharactersWithinUpdateRange, List<MapItem> MapItemsInRange, CreatureBase creatureToAttack)
        {
            int atkDelay = 0;
            bool rushAttacked = false;

            List<MapItem> MapItemsToUpdate = new List<MapItem>();

            //maxMoves is used so we can change this number in the loop if the creature moves through
            //terrain that reduces movement (water , sand)
            int maxMoves = ChosenPath.Count - 1;

            for (int x = 0; x <= maxMoves; x++)
            {
                MapItem mapitem = ChosenPath[x];
                bool updateMapItem = false;

                //Check Hex Motion and reduce max turns
                int allowedMotion = mapitem.CreatureMotion();
                if (mapitem.TerrainType == "Water" && MyCreature.WaterMotion > allowedMotion)
                    allowedMotion = MyCreature.WaterMotion;

                //Check Hex Motion and reduce max turns
                if (allowedMotion < maxMoves)
                {
                    maxMoves = allowedMotion;
                }

                //Open Doors
                if (mapitem.TerrainType == "Door")
                {
                    if (mapitem.Transparent == false)
                    {
                        mapitem.Transparent = true;
                        mapitem.TerrainUrl = mapitem.TerrainUrl.Replace("Closed", "Open");

                        foreach (Character character in CharactersWithinUpdateRange)
                        {
                            if (Math.Abs(character.MapX - mapitem.MapX) <= 8 && Math.Abs(character.MapY - mapitem.MapY) <= 8)
                                character.PlaySound("DoorOpen", mapitem.MapX, mapitem.MapY);
                        }

                        updateMapItem = true;
                    }
                }

                //First move
                if (x == 0)
                {
                    mapitem.CreaturesBases.Remove(this.MyCreature);
                    updateMapItem = true;
                }
                //Last Move
                else if (x >= maxMoves)
                {
                    List<CreatureBase> AttackableCreatures = new List<CreatureBase>();
                    foreach (CreatureBase creaturebase in mapitem.CreaturesBases)
                    {
                        if ((creaturebase.Faction != MyCreature.Faction || MyCreature.hateManager.GetCreatureHateInfo(creaturebase) != null) && creaturebase.HP > 0)
                        {
                            if (creaturebase.CanSeeMe(MyCreature))
                                AttackableCreatures.Add(creaturebase);
                        }
                    }

                    //Add creature first, SetPosition() might cause an effect that could cause the creature to be removed
                    mapitem.CreaturesBases.Add(MyCreature);

                    MyCreature.SetPosition(mapitem);

                    //Check if we are on a stair hex, if we are record how many attackable creatures are here
                    //This is used to determine if the creature needs to chase something up or down stairs
                    if (mapitem.TerrainType == "StairsUp" || mapitem.TerrainType == "StairsDown")
                        numAttackableCreaturesOnStairs = AttackableCreatures.Count;
                    else
                        numAttackableCreaturesOnStairs = 0;

                    //Make sure creature to attack is on our tile (We may not have made it through the entire path due to movement restriction like water)
                    if (creatureToAttack != null && (creatureToAttack.MapX != mapitem.MapX || creatureToAttack.MapY != mapitem.MapY || creatureToAttack.MapID != MyCreature.MapID))
                        creatureToAttack = null;

                    if (MyCreature.RushAttack == true && creatureToAttack != null && MyCreature.attackSequenceManager.CurrentAction is CreatureAttackWeapon)
                    {
                        rushAttacked = true;

                        //Returns true if attack is successfull, false if blocked or miss
                        if (MyCreature.AttackCreatureBase(CharactersWithinUpdateRange, creatureToAttack, MapItemsInRange, false, out atkDelay) == true)
                            creatureToAttack.Update_Character();

                        //If creature is dead, remove char
                        if (creatureToAttack.HP < 1)
                        {
                            if (!(creatureToAttack is Character)) 
                                mapitem.CreaturesBases.Remove(creatureToAttack);
                        }

                    }

                    updateMapItem = true;
                }

                if (updateMapItem == true)
                    MapItemsToUpdate.Add(mapitem);
            }
            foreach (Character character in CharactersWithinUpdateRange)
            {
                character.AddMapItems(MapItemsToUpdate, false);
            }

            double totalDelay = System.Convert.ToDouble(MyCreature.MovementSpeed) * 1000;

            if (rushAttacked == true)
                totalDelay = totalDelay + System.Convert.ToDouble(atkDelay);

            Timer_CreatureRound.Interval = totalDelay;
            Timer_CreatureRound.Start();
        }

        //Helper function tell us if we're pathing to a position we already have
        private static bool pathOptionExists(List<List<MapItem>> Paths, Point Position)
        {
            foreach (List<MapItem> Path in Paths)
            {
                foreach (MapItem mapitem in Path)
                {
                    if (mapitem.MapX == Position.X && mapitem.MapY == Position.Y)
                        return true;
                }
            }
            return false;
        }

        //Finds all available paths within supplied map items, per creatures abilities, 
        public static List<List<MapItem>> FindAllPaths(CreatureBase MyCreatureBase, List<MapItem> CreatureMapItems, MapItem CurrentMapItem)
        {
            return FindAllPaths(MyCreatureBase, CreatureMapItems, CurrentMapItem, 4);
        }
        public static List<List<MapItem>> FindAllPaths(CreatureBase MyCreatureBase, List<MapItem> CreatureMapItems, MapItem CurrentMapItem, int MaxMoves)
        {
            //We are going to do a lot of single lookups on these map items, so we're going to put the data in a dictionary for speed
            Dictionary<string, MapItem> creaturemapitems = new Dictionary<string, MapItem>();
            foreach (MapItem mapitem in CreatureMapItems)
            {
                creaturemapitems.Add(mapitem.MapX + "," + mapitem.MapY, mapitem);
            }

            //Return list
            List<List<MapItem>> Paths = new List<List<MapItem>>();

            //Temp Items used durring path building loop
            List<MapItem> Path = new List<MapItem>();
            MapItem MapItemToAdd = null;
            List<List<MapItem>> PathsToAdd = new List<List<MapItem>>();

            //Start with our current position (this may be the only path)
            Path.Add(CurrentMapItem);
            //Add our position to return list
            Paths.Add(Path);

            //Return just our current hex if the creature cannot move due to spell effect
            if (CurrentMapItem.CreatureMotion() == 0 || MyCreatureBase.buffManager.IsRooted() != "")
                return Paths;

            //FIND ALL PATHS WITHIN 4 Moves (Even though not all creatures can make 4 moves we need to know
            //which creatures are accessable and which creatures we cannot reach AKA, they are in water or behind counters
            for (int x = 0; x < MaxMoves; x++)
            {
                //List of new paths to add to main list of paths
                PathsToAdd = new List<List<MapItem>>();

                //Cycle through all the paths we already have
                for (int y = 0; y < Paths.Count; y++)
                {
                    //Skip paths that have already dead ended
                    if (Paths[y].Count < x + 1)
                        continue;

                    MapItemToAdd = null;
                    bool FoundPath = false;

                    //Create a copy of the current path so we can make a new path with it
                    List<MapItem> path = new List<MapItem>();
                    for (int t = 0; t < Paths[y].Count; t++)
                    {
                        path.Add(Paths[y][t]);
                    }

                    //Get the positions to check, prioritized depending on current heading
                    List<Point> PathOptions = new List<Point>();
                    if (path.Count > 1)
                        PathOptions = positionsToCheck(new Point(path[path.Count - 1].MapX, path[path.Count - 1].MapY), new Point(path[path.Count - 2].MapX, path[path.Count - 2].MapY));
                    else
                        PathOptions = positionsToCheck(new Point(path[path.Count - 1].MapX, path[path.Count - 1].MapY), null);

                    foreach (Point position in PathOptions)
                    {
                        MapItem Mapitem;
                        if (creaturemapitems.TryGetValue(position.X.ToString() + "," + position.Y.ToString(), out Mapitem))
                        {
                            if ((MyCreatureBase.Water == true && Mapitem.TerrainType == "Water") || (MyCreatureBase.Air == true && Mapitem.TerrainType == "Air") ||
                                MyCreatureBase.Land == true && Mapitem.TerrainType != "Water" && Mapitem.TerrainType != "Air")
                            {
                                if (Mapitem.CreatureMotion() != 0 && pathOptionExists(Paths, position) == false)
                                {
                                    if (FoundPath == false)
                                    {
                                        MapItemToAdd = Mapitem;
                                    }
                                    else
                                    {
                                        List<MapItem> PathToAdd = new List<MapItem>();
                                        for (int h = 0; h < path.Count; h++)
                                        {
                                            PathToAdd.Add(path[h]);
                                        }
                                        PathToAdd.Add(Mapitem);
                                        PathsToAdd.Add(PathToAdd);
                                    }
                                    FoundPath = true;
                                }
                            }
                        }
                    }
                    if (FoundPath == true)
                        Paths[y].Add(MapItemToAdd);
                }
                for (int z = 0; z < PathsToAdd.Count; z++)
                {
                    Paths.Add(PathsToAdd[z]);
                }
            }
            return Paths;
        }

        //Simple helper function check hidden list for position and return true or false
        public static bool isHidden(int MapX, int MapY, List<Point> HiddenList)
        {
            foreach (Point point in HiddenList)
            {
                if (point.X == MapX && point.Y == MapY)
                    return true;
            }
            return false;
        }

        //Locates Hidden map points (This is used for messages, and spells)
        //TODO: This is terribly written, figure out math to do this rather than hard coding ever senario
        public static List<Point> FindHidden(int MapX, int MapY, List<MapItem> MapItems)
        {
            List<Point> HiddenList = new List<Point>();
            Point PointToAdd = new Point();
            for (int x = 0; x < MapItems.Count; x++)
            {
                //NW
                if (MapItems[x].MapX - MapX == -1 && MapItems[x].MapY - MapY == -1)
                {
                    if (MapItems[x].Transparent == false)
                    {
                        //ADD TO HIDDEN
                        PointToAdd = new Point(MapX - 2, MapY - 2);
                        HiddenList.Add(PointToAdd);
                        PointToAdd = new Point(MapX - 2, MapY - 3);
                        HiddenList.Add(PointToAdd);
                        PointToAdd = new Point(MapX - 2, MapY - 4);
                        HiddenList.Add(PointToAdd);

                        PointToAdd = new Point(MapX - 3, MapY - 2);
                        HiddenList.Add(PointToAdd);
                        PointToAdd = new Point(MapX - 3, MapY - 3);
                        HiddenList.Add(PointToAdd);
                        PointToAdd = new Point(MapX - 3, MapY - 4);
                        HiddenList.Add(PointToAdd);

                        PointToAdd = new Point(MapX - 4, MapY - 2);
                        HiddenList.Add(PointToAdd);
                        PointToAdd = new Point(MapX - 4, MapY - 3);
                        HiddenList.Add(PointToAdd);
                        PointToAdd = new Point(MapX - 4, MapY - 4);
                        HiddenList.Add(PointToAdd);
                    }
                }
                //N
                else if (MapItems[x].MapX - MapX == 0 && MapItems[x].MapY - MapY == -1)
                {
                    if (MapItems[x].Transparent == false)
                    {
                        //ADD TO HIDDEN
                        PointToAdd = new Point(MapX - 0, MapY - 2);
                        HiddenList.Add(PointToAdd);
                        PointToAdd = new Point(MapX - 0, MapY - 3);
                        HiddenList.Add(PointToAdd);
                        PointToAdd = new Point(MapX - 0, MapY - 4);
                        HiddenList.Add(PointToAdd);

                        //Check NW
                        for (int y = 0; y < MapItems.Count; y++)
                        {
                            if (MapItems[y].MapX - MapX == -1 && MapItems[y].MapY - MapY == -1)
                            {
                                if (MapItems[y].Transparent == false)
                                {
                                    //ADD TO HIDDEN
                                    PointToAdd = new Point(MapX - 1, MapY - 2);
                                    HiddenList.Add(PointToAdd);
                                    PointToAdd = new Point(MapX - 1, MapY - 3);
                                    HiddenList.Add(PointToAdd);
                                    PointToAdd = new Point(MapX - 2, MapY - 3);
                                    HiddenList.Add(PointToAdd);
                                    PointToAdd = new Point(MapX - 1, MapY - 4);
                                    HiddenList.Add(PointToAdd);
                                    PointToAdd = new Point(MapX - 2, MapY - 4);
                                    HiddenList.Add(PointToAdd);
                                }
                                break;
                            }
                        }
                        //CHECK NE
                        for (int z = 0; z < MapItems.Count; z++)
                        {
                            if (MapItems[z].MapX - MapX == 1 && MapItems[z].MapY - MapY == -1)
                            {
                                if (MapItems[z].Transparent == false)
                                {
                                    //ADD TO HIDDEN
                                    PointToAdd = new Point(MapX + 1, MapY - 2);
                                    HiddenList.Add(PointToAdd);
                                    PointToAdd = new Point(MapX + 1, MapY - 3);
                                    HiddenList.Add(PointToAdd);
                                    PointToAdd = new Point(MapX + 2, MapY - 3);
                                    HiddenList.Add(PointToAdd);
                                    PointToAdd = new Point(MapX + 1, MapY - 4);
                                    HiddenList.Add(PointToAdd);
                                    PointToAdd = new Point(MapX + 2, MapY - 4);
                                    HiddenList.Add(PointToAdd);
                                }
                                break;
                            }
                        }
                    }
                }
                //NE
                else if (MapItems[x].MapX - MapX == 1 && MapItems[x].MapY - MapY == -1)
                {
                    if (MapItems[x].Transparent == false)
                    {
                        //ADD TO HIDDEN
                        PointToAdd = new Point(MapX + 2, MapY - 2);
                        HiddenList.Add(PointToAdd);
                        PointToAdd = new Point(MapX + 2, MapY - 3);
                        HiddenList.Add(PointToAdd);
                        PointToAdd = new Point(MapX + 2, MapY - 4);
                        HiddenList.Add(PointToAdd);

                        PointToAdd = new Point(MapX + 3, MapY - 2);
                        HiddenList.Add(PointToAdd);
                        PointToAdd = new Point(MapX + 3, MapY - 3);
                        HiddenList.Add(PointToAdd);
                        PointToAdd = new Point(MapX + 3, MapY - 4);
                        HiddenList.Add(PointToAdd);

                        PointToAdd = new Point(MapX + 4, MapY - 2);
                        HiddenList.Add(PointToAdd);
                        PointToAdd = new Point(MapX + 4, MapY - 3);
                        HiddenList.Add(PointToAdd);
                        PointToAdd = new Point(MapX + 4, MapY - 4);
                        HiddenList.Add(PointToAdd);
                    }
                }

                //E
                else if (MapItems[x].MapX - MapX == 1 && MapItems[x].MapY - MapY == 0)
                {
                    if (MapItems[x].Transparent == false)
                    {
                        //ADD TO HIDDEN
                        PointToAdd = new Point(MapX + 2, MapY - 0);
                        HiddenList.Add(PointToAdd);
                        PointToAdd = new Point(MapX + 3, MapY - 0);
                        HiddenList.Add(PointToAdd);
                        PointToAdd = new Point(MapX + 4, MapY - 0);
                        HiddenList.Add(PointToAdd);

                        //Check NE
                        for (int y = 0; y < MapItems.Count; y++)
                        {
                            if (MapItems[y].MapX - MapX == 1 && MapItems[y].MapY - MapY == -1)
                            {
                                if (MapItems[y].Transparent == false)
                                {
                                    //ADD TO HIDDEN
                                    PointToAdd = new Point(MapX + 2, MapY - 1);
                                    HiddenList.Add(PointToAdd);
                                    PointToAdd = new Point(MapX + 3, MapY - 1);
                                    HiddenList.Add(PointToAdd);
                                    PointToAdd = new Point(MapX + 3, MapY - 2);
                                    HiddenList.Add(PointToAdd);
                                    PointToAdd = new Point(MapX + 4, MapY - 1);
                                    HiddenList.Add(PointToAdd);
                                    PointToAdd = new Point(MapX + 4, MapY - 2);
                                    HiddenList.Add(PointToAdd);
                                }
                                break;
                            }
                        }
                        //CHECK SE
                        for (int z = 0; z < MapItems.Count; z++)
                        {
                            if (MapItems[z].MapX - MapX == 1 && MapItems[z].MapY - MapY == 1)
                            {
                                if (MapItems[z].Transparent == false)
                                {
                                    //ADD TO HIDDEN
                                    PointToAdd = new Point(MapX + 2, MapY + 1);
                                    HiddenList.Add(PointToAdd);
                                    PointToAdd = new Point(MapX + 3, MapY + 1);
                                    HiddenList.Add(PointToAdd);
                                    PointToAdd = new Point(MapX + 3, MapY + 2);
                                    HiddenList.Add(PointToAdd);
                                    PointToAdd = new Point(MapX + 4, MapY + 1);
                                    HiddenList.Add(PointToAdd);
                                    PointToAdd = new Point(MapX + 4, MapY + 2);
                                    HiddenList.Add(PointToAdd);
                                }
                                break;
                            }
                        }
                    }
                }
                //SE
                else if (MapItems[x].MapX - MapX == 1 && MapItems[x].MapY - MapY == 1)
                {
                    if (MapItems[x].Transparent == false)
                    {
                        //ADD TO HIDDEN
                        PointToAdd = new Point(MapX + 2, MapY + 2);
                        HiddenList.Add(PointToAdd);
                        PointToAdd = new Point(MapX + 2, MapY + 3);
                        HiddenList.Add(PointToAdd);
                        PointToAdd = new Point(MapX + 2, MapY + 4);
                        HiddenList.Add(PointToAdd);

                        PointToAdd = new Point(MapX + 3, MapY + 2);
                        HiddenList.Add(PointToAdd);
                        PointToAdd = new Point(MapX + 3, MapY + 3);
                        HiddenList.Add(PointToAdd);
                        PointToAdd = new Point(MapX + 3, MapY + 4);
                        HiddenList.Add(PointToAdd);

                        PointToAdd = new Point(MapX + 4, MapY + 2);
                        HiddenList.Add(PointToAdd);
                        PointToAdd = new Point(MapX + 4, MapY + 3);
                        HiddenList.Add(PointToAdd);
                        PointToAdd = new Point(MapX + 4, MapY + 4);
                        HiddenList.Add(PointToAdd);
                    }
                }
                //S
                else if (MapItems[x].MapX - MapX == 0 && MapItems[x].MapY - MapY == 1)
                {
                    if (MapItems[x].Transparent == false)
                    {
                        //ADD TO HIDDEN
                        PointToAdd = new Point(MapX + 0, MapY + 2);
                        HiddenList.Add(PointToAdd);
                        PointToAdd = new Point(MapX + 0, MapY + 3);
                        HiddenList.Add(PointToAdd);
                        PointToAdd = new Point(MapX + 0, MapY + 4);
                        HiddenList.Add(PointToAdd);

                        //Check SE
                        for (int y = 0; y < MapItems.Count; y++)
                        {
                            if (MapItems[y].MapX - MapX == 1 && MapItems[y].MapY - MapY == 1)
                            {
                                if (MapItems[y].Transparent == false)
                                {
                                    //ADD TO HIDDEN
                                    PointToAdd = new Point(MapX + 1, MapY + 2);
                                    HiddenList.Add(PointToAdd);
                                    PointToAdd = new Point(MapX + 1, MapY + 3);
                                    HiddenList.Add(PointToAdd);
                                    PointToAdd = new Point(MapX + 2, MapY + 3);
                                    HiddenList.Add(PointToAdd);
                                    PointToAdd = new Point(MapX + 1, MapY + 4);
                                    HiddenList.Add(PointToAdd);
                                    PointToAdd = new Point(MapX + 2, MapY + 4);
                                    HiddenList.Add(PointToAdd);
                                }
                                break;
                            }
                        }
                        //CHECK SW
                        for (int z = 0; z < MapItems.Count; z++)
                        {
                            if (MapItems[z].MapX - MapX == -1 && MapItems[z].MapY - MapY == 1)
                            {
                                if (MapItems[z].Transparent == false)
                                {
                                    //ADD TO HIDDEN
                                    PointToAdd = new Point(MapX - 1, MapY + 2);
                                    HiddenList.Add(PointToAdd);
                                    PointToAdd = new Point(MapX - 1, MapY + 3);
                                    HiddenList.Add(PointToAdd);
                                    PointToAdd = new Point(MapX - 2, MapY + 3);
                                    HiddenList.Add(PointToAdd);
                                    PointToAdd = new Point(MapX - 1, MapY + 4);
                                    HiddenList.Add(PointToAdd);
                                    PointToAdd = new Point(MapX - 2, MapY + 4);
                                    HiddenList.Add(PointToAdd);
                                }
                                break;
                            }
                        }
                    }
                }
                //SW
                else if (MapItems[x].MapX - MapX == -1 && MapItems[x].MapY - MapY == 1)
                {
                    if (MapItems[x].Transparent == false)
                    {
                        //ADD TO HIDDEN
                        PointToAdd = new Point(MapX - 2, MapY + 2);
                        HiddenList.Add(PointToAdd);
                        PointToAdd = new Point(MapX - 2, MapY + 3);
                        HiddenList.Add(PointToAdd);
                        PointToAdd = new Point(MapX - 2, MapY + 4);
                        HiddenList.Add(PointToAdd);

                        PointToAdd = new Point(MapX - 3, MapY + 2);
                        HiddenList.Add(PointToAdd);
                        PointToAdd = new Point(MapX - 3, MapY + 3);
                        HiddenList.Add(PointToAdd);
                        PointToAdd = new Point(MapX - 3, MapY + 4);
                        HiddenList.Add(PointToAdd);

                        PointToAdd = new Point(MapX - 4, MapY + 2);
                        HiddenList.Add(PointToAdd);
                        PointToAdd = new Point(MapX - 4, MapY + 3);
                        HiddenList.Add(PointToAdd);
                        PointToAdd = new Point(MapX - 4, MapY + 4);
                        HiddenList.Add(PointToAdd);
                    }
                }
                //W
                else if (MapItems[x].MapX - MapX == -1 && MapItems[x].MapY - MapY == 0)
                {
                    if (MapItems[x].Transparent == false)
                    {
                        //ADD TO HIDDEN
                        PointToAdd = new Point(MapX - 2, MapY + 0);
                        HiddenList.Add(PointToAdd);
                        PointToAdd = new Point(MapX - 3, MapY + 0);
                        HiddenList.Add(PointToAdd);
                        PointToAdd = new Point(MapX - 4, MapY + 0);
                        HiddenList.Add(PointToAdd);

                        //Check SW
                        for (int y = 0; y < MapItems.Count; y++)
                        {
                            if (MapItems[y].MapX - MapX == -1 && MapItems[y].MapY - MapY == 1)
                            {
                                if (MapItems[y].Transparent == false)
                                {
                                    //ADD TO HIDDEN
                                    PointToAdd = new Point(MapX - 2, MapY + 1);
                                    HiddenList.Add(PointToAdd);
                                    PointToAdd = new Point(MapX - 3, MapY + 1);
                                    HiddenList.Add(PointToAdd);
                                    PointToAdd = new Point(MapX - 3, MapY + 2);
                                    HiddenList.Add(PointToAdd);
                                    PointToAdd = new Point(MapX - 4, MapY + 1);
                                    HiddenList.Add(PointToAdd);
                                    PointToAdd = new Point(MapX - 4, MapY + 2);
                                    HiddenList.Add(PointToAdd);
                                }
                                break;
                            }
                        }
                        //CHECK NW
                        for (int z = 0; z < MapItems.Count; z++)
                        {
                            if (MapItems[z].MapX - MapX == -1 && MapItems[z].MapY - MapY == -1)
                            {
                                if (MapItems[z].Transparent == false)
                                {
                                    //ADD TO HIDDEN
                                    PointToAdd = new Point(MapX - 2, MapY - 1);
                                    HiddenList.Add(PointToAdd);
                                    PointToAdd = new Point(MapX - 3, MapY - 1);
                                    HiddenList.Add(PointToAdd);
                                    PointToAdd = new Point(MapX - 3, MapY - 2);
                                    HiddenList.Add(PointToAdd);
                                    PointToAdd = new Point(MapX - 4, MapY - 1);
                                    HiddenList.Add(PointToAdd);
                                    PointToAdd = new Point(MapX - 4, MapY - 2);
                                    HiddenList.Add(PointToAdd);
                                }
                                break;
                            }
                        }
                    }
                }
                /////////////////////////////////////////////////////

                //NW NW
                else if (MapItems[x].MapX - MapX == -2 && MapItems[x].MapY - MapY == -2)
                {
                    if (MapItems[x].Transparent == false)
                    {
                        //ADD TO HIDDEN
                        PointToAdd = new Point(MapX - 3, MapY - 3);
                        HiddenList.Add(PointToAdd);
                        PointToAdd = new Point(MapX - 4, MapY - 4);
                        HiddenList.Add(PointToAdd);
			            PointToAdd = new Point(MapX - 3, MapY - 4);
                        HiddenList.Add(PointToAdd);
                        PointToAdd = new Point(MapX - 4, MapY - 3);
                        HiddenList.Add(PointToAdd);
                    }
                }
                //NW N
                else if (MapItems[x].MapX - MapX == -1 && MapItems[x].MapY - MapY == -2)
                {
                    if (MapItems[x].Transparent == false)
                    {
                        //ADD TO HIDDEN
                        PointToAdd = new Point(MapX - 2, MapY - 3);
                        HiddenList.Add(PointToAdd);
                        PointToAdd = new Point(MapX - 2, MapY - 4);
                        HiddenList.Add(PointToAdd);
                        PointToAdd = new Point(MapX - 3, MapY - 4);
                        HiddenList.Add(PointToAdd);
                    }
                }
                //N N
                else if (MapItems[x].MapX - MapX == -0 && MapItems[x].MapY - MapY == -2)
                {
                    if (MapItems[x].Transparent == false)
                    {
                        //ADD TO HIDDEN
                        PointToAdd = new Point(MapX - 0, MapY - 3);
                        HiddenList.Add(PointToAdd);
                        PointToAdd = new Point(MapX - 0, MapY - 4);
                        HiddenList.Add(PointToAdd);


                        //Check WN N
                        for (int y = 0; y < MapItems.Count; y++)
                        {
                            if (MapItems[y].MapX - MapX == -1 && MapItems[y].MapY - MapY == -2)
                            {
                                if (MapItems[y].Transparent == false)
                                {
                                    //ADD TO HIDDEN
                                    PointToAdd = new Point(MapX - 1, MapY - 3);
                                    HiddenList.Add(PointToAdd);
                                    PointToAdd = new Point(MapX - 1, MapY - 4);
                                    HiddenList.Add(PointToAdd);
                                }
                                break;
                            }
                        }
                        //CHECK NE N
                        for (int z = 0; z < MapItems.Count; z++)
                        {
                            if (MapItems[z].MapX - MapX == +1 && MapItems[z].MapY - MapY == -2)
                            {
                                if (MapItems[z].Transparent == false)
                                {
                                    //ADD TO HIDDEN
                                    PointToAdd = new Point(MapX + 1, MapY - 3);
                                    HiddenList.Add(PointToAdd);
                                    PointToAdd = new Point(MapX + 1, MapY - 4);
                                    HiddenList.Add(PointToAdd);
                                }
                                break;
                            }
                        }
                    }
                }
                //NE N
                else if (MapItems[x].MapX - MapX == +1 && MapItems[x].MapY - MapY == -2)
                {
                    if (MapItems[x].Transparent == false)
                    {
                        //ADD TO HIDDEN
                        PointToAdd = new Point(MapX + 2, MapY - 3);
                        HiddenList.Add(PointToAdd);
                        PointToAdd = new Point(MapX + 2, MapY - 4);
                        HiddenList.Add(PointToAdd);
                        PointToAdd = new Point(MapX + 3, MapY - 4);
                        HiddenList.Add(PointToAdd);

                    }
                }
                //NE NE
                else if (MapItems[x].MapX - MapX == +2 && MapItems[x].MapY - MapY == -2)
                {
                    if (MapItems[x].Transparent == false)
                    {
                        //ADD TO HIDDEN
                        PointToAdd = new Point(MapX + 3, MapY - 3);
                        HiddenList.Add(PointToAdd);
                        PointToAdd = new Point(MapX + 4, MapY - 4);
                        HiddenList.Add(PointToAdd);
			            PointToAdd = new Point(MapX + 3, MapY - 4);
                        HiddenList.Add(PointToAdd);
                        PointToAdd = new Point(MapX + 4, MapY - 3);
                        HiddenList.Add(PointToAdd);
                    }
                }
                //NE E
                else if (MapItems[x].MapX - MapX == +2 && MapItems[x].MapY - MapY == -1)
                {
                    if (MapItems[x].Transparent == false)
                    {
                        //ADD TO HIDDEN
                        PointToAdd = new Point(MapX + 3, MapY - 2);
                        HiddenList.Add(PointToAdd);
                        PointToAdd = new Point(MapX + 4, MapY - 2);
                        HiddenList.Add(PointToAdd);
                        PointToAdd = new Point(MapX + 4, MapY - 3);
                        HiddenList.Add(PointToAdd);
                    }
                }
                //E E
                else if (MapItems[x].MapX - MapX == +2 && MapItems[x].MapY - MapY == -0)
                {
                    if (MapItems[x].Transparent == false)
                    {
                        //ADD TO HIDDEN
                        PointToAdd = new Point(MapX + 3, MapY + 0);
                        HiddenList.Add(PointToAdd);
                        PointToAdd = new Point(MapX + 4, MapY + 0);
                        HiddenList.Add(PointToAdd);

                        //Check NE E
                        for (int y = 0; y < MapItems.Count; y++)
                        {
                            if (MapItems[y].MapX - MapX == +2 && MapItems[y].MapY - MapY == -1)
                            {
                                if (MapItems[y].Transparent == false)
                                {
                                    //ADD TO HIDDEN
                                    PointToAdd = new Point(MapX + 3, MapY - 1);
                                    HiddenList.Add(PointToAdd);
                                    PointToAdd = new Point(MapX + 4, MapY - 1);
                                    HiddenList.Add(PointToAdd);
                                    PointToAdd = new Point(MapX + 4, MapY - 2);
                                    HiddenList.Add(PointToAdd);
                                }
                                break;
                            }
                        }
                        //CHECK SE N
                        for (int z = 0; z < MapItems.Count; z++)
                        {
                            if (MapItems[z].MapX - MapX == +2 && MapItems[z].MapY - MapY == +1)
                            {
                                if (MapItems[z].Transparent == false)
                                {
                                    //ADD TO HIDDEN
                                    PointToAdd = new Point(MapX + 3, MapY + 1);
                                    HiddenList.Add(PointToAdd);
                                    PointToAdd = new Point(MapX + 4, MapY + 1);
                                    HiddenList.Add(PointToAdd);
                                    PointToAdd = new Point(MapX + 4, MapY + 2);
                                    HiddenList.Add(PointToAdd);
                                }
                                break;
                            }
                        }
                    }
                }
                //SE E
                else if (MapItems[x].MapX - MapX == +2 && MapItems[x].MapY - MapY == +1)
                {
                    if (MapItems[x].Transparent == false)
                    {
                        //ADD TO HIDDEN
                        PointToAdd = new Point(MapX + 3, MapY + 2);
                        HiddenList.Add(PointToAdd);
                        PointToAdd = new Point(MapX + 4, MapY + 2);
                        HiddenList.Add(PointToAdd);
                        PointToAdd = new Point(MapX + 4, MapY + 3);
                        HiddenList.Add(PointToAdd);
                    }
                }
                //SE SE
                else if (MapItems[x].MapX - MapX == +2 && MapItems[x].MapY - MapY == +2)
                {
                    if (MapItems[x].Transparent == false)
                    {
                        //ADD TO HIDDEN
                        PointToAdd = new Point(MapX + 3, MapY + 3);
                        HiddenList.Add(PointToAdd);
                        PointToAdd = new Point(MapX + 4, MapY + 4);
                        HiddenList.Add(PointToAdd);
			            PointToAdd = new Point(MapX + 3, MapY + 4);
                        HiddenList.Add(PointToAdd);
                        PointToAdd = new Point(MapX + 4, MapY + 3);
                        HiddenList.Add(PointToAdd);
                    }
                }
                //SE S
                else if (MapItems[x].MapX - MapX == +1 && MapItems[x].MapY - MapY == +2)
                {
                    if (MapItems[x].Transparent == false)
                    {
                        //ADD TO HIDDEN
                        PointToAdd = new Point(MapX + 2, MapY + 3);
                        HiddenList.Add(PointToAdd);
                        PointToAdd = new Point(MapX + 2, MapY + 4);
                        HiddenList.Add(PointToAdd);
                        PointToAdd = new Point(MapX + 3, MapY + 4);
                        HiddenList.Add(PointToAdd);
                    }
                }
                //S S  
                else if (MapItems[x].MapX - MapX == +0 && MapItems[x].MapY - MapY == +2)
                {
                    if (MapItems[x].Transparent == false)
                    {
                        //ADD TO HIDDEN
                        PointToAdd = new Point(MapX + 0, MapY + 3);
                        HiddenList.Add(PointToAdd);
                        PointToAdd = new Point(MapX + 0, MapY + 4);
                        HiddenList.Add(PointToAdd);

                        //Check SE E
                        for (int y = 0; y < MapItems.Count; y++)
                        {
                            if (MapItems[y].MapX - MapX == +1 && MapItems[y].MapY - MapY == +2)
                            {
                                if (MapItems[y].Transparent == false)
                                {
                                    //ADD TO HIDDEN
                                    PointToAdd = new Point(MapX + 1, MapY + 3);
                                    HiddenList.Add(PointToAdd);
                                    PointToAdd = new Point(MapX + 1, MapY + 4);
                                    HiddenList.Add(PointToAdd);
                                    PointToAdd = new Point(MapX + 2, MapY + 4);
                                    HiddenList.Add(PointToAdd);
                                }
                                break;
                            }
                        }
                        //CHECK SW S
                        for (int z = 0; z < MapItems.Count; z++)
                        {
                            if (MapItems[z].MapX - MapX == -1 && MapItems[z].MapY - MapY == +2)
                            {
                                if (MapItems[z].Transparent == false)
                                {
                                    //ADD TO HIDDEN
                                    PointToAdd = new Point(MapX - 1, MapY + 3);
                                    HiddenList.Add(PointToAdd);
                                    PointToAdd = new Point(MapX - 1, MapY + 4);
                                    HiddenList.Add(PointToAdd);
                                    PointToAdd = new Point(MapX - 2, MapY + 4);
                                    HiddenList.Add(PointToAdd);
                                }
                                break;
                            }
                        }
                    }
                }
                //SW S
                else if (MapItems[x].MapX - MapX == -1 && MapItems[x].MapY - MapY == +2)
                {
                    if (MapItems[x].Transparent == false)
                    {
                        //ADD TO HIDDEN
                        PointToAdd = new Point(MapX - 2, MapY + 3);
                        HiddenList.Add(PointToAdd);
                        PointToAdd = new Point(MapX - 3, MapY + 4);
                        HiddenList.Add(PointToAdd);
                        PointToAdd = new Point(MapX - 2, MapY + 4);
                        HiddenList.Add(PointToAdd);
                    }
                }
                //SW SW
                else if (MapItems[x].MapX - MapX == -2 && MapItems[x].MapY - MapY == +2)
                {
                    if (MapItems[x].Transparent == false)
                    {
                        //ADD TO HIDDEN
                        PointToAdd = new Point(MapX - 3, MapY + 3);
                        HiddenList.Add(PointToAdd);
                        PointToAdd = new Point(MapX - 4, MapY + 4);
                        HiddenList.Add(PointToAdd);
			            PointToAdd = new Point(MapX - 3, MapY + 4);
                        HiddenList.Add(PointToAdd);
                        PointToAdd = new Point(MapX - 4, MapY + 3);
                        HiddenList.Add(PointToAdd);
                    }
                }
                //SW W
                else if (MapItems[x].MapX - MapX == -2 && MapItems[x].MapY - MapY == +1)
                {
                    if (MapItems[x].Transparent == false)
                    {
                        //ADD TO HIDDEN
                        PointToAdd = new Point(MapX - 3, MapY + 2);
                        HiddenList.Add(PointToAdd);
                        PointToAdd = new Point(MapX - 4, MapY + 2);
                        HiddenList.Add(PointToAdd);
                        PointToAdd = new Point(MapX - 4, MapY + 3);
                        HiddenList.Add(PointToAdd);
                    }
                }
                //W W
                else if (MapItems[x].MapX - MapX == -2 && MapItems[x].MapY - MapY == +0)
                {
                    if (MapItems[x].Transparent == false)
                    {
                        //ADD TO HIDDEN
                        PointToAdd = new Point(MapX - 3, MapY + 0);
                        HiddenList.Add(PointToAdd);
                        PointToAdd = new Point(MapX - 4, MapY + 0);
                        HiddenList.Add(PointToAdd);

                        //Check SW W
                        for (int y = 0; y < MapItems.Count; y++)
                        {
                            if (MapItems[y].MapX - MapX == -2 && MapItems[y].MapY - MapY == +1)
                            {
                                if (MapItems[y].Transparent == false)
                                {
                                    //ADD TO HIDDEN
                                    PointToAdd = new Point(MapX - 3, MapY + 1);
                                    HiddenList.Add(PointToAdd);
                                    PointToAdd = new Point(MapX - 4, MapY + 1);
                                    HiddenList.Add(PointToAdd);
                                    PointToAdd = new Point(MapX - 4, MapY + 2);
                                    HiddenList.Add(PointToAdd);
                                }
                                break;
                            }
                        }
                        //CHECK NW W
                        for (int z = 0; z < MapItems.Count; z++)
                        {
                            if (MapItems[z].MapX - MapX == -2 && MapItems[z].MapY - MapY == -1)
                            {
                                if (MapItems[z].Transparent == false)
                                {
                                    //ADD TO HIDDEN
                                    PointToAdd = new Point(MapX - 3, MapY - 1);
                                    HiddenList.Add(PointToAdd);
                                    PointToAdd = new Point(MapX - 4, MapY - 1);
                                    HiddenList.Add(PointToAdd);
                                    PointToAdd = new Point(MapX - 4, MapY - 2);
                                    HiddenList.Add(PointToAdd);
                                }
                                break;
                            }
                        }
                    }
                }
                //W NW
                else if (MapItems[x].MapX - MapX == -2 && MapItems[x].MapY - MapY == -1)
                {
                    if (MapItems[x].Transparent == false)
                    {
                        //ADD TO HIDDEN
                        PointToAdd = new Point(MapX - 3, MapY - 2);
                        HiddenList.Add(PointToAdd);
                        PointToAdd = new Point(MapX - 4, MapY - 2);
                        HiddenList.Add(PointToAdd);
                        PointToAdd = new Point(MapX - 4, MapY - 3);
                        HiddenList.Add(PointToAdd);
                    }
                }
                //////////////////////////////////////////////////////////////

                //NW NW NW
                else if (MapItems[x].MapX - MapX == -3 && MapItems[x].MapY - MapY == -3)
                {
                    if (MapItems[x].Transparent == false)
                    {
                        //ADD TO HIDDEN
                        PointToAdd = new Point(MapX - 4, MapY - 4);
                        HiddenList.Add(PointToAdd);
                    }
                }
                //NW NW N
                else if (MapItems[x].MapX - MapX == -2 && MapItems[x].MapY - MapY == -3)
                {
                    if (MapItems[x].Transparent == false)
                    {
                        //ADD TO HIDDEN
                        PointToAdd = new Point(MapX - 3, MapY - 4);
                        HiddenList.Add(PointToAdd);
                    }
                }
                //NW N N
                else if (MapItems[x].MapX - MapX == -1 && MapItems[x].MapY - MapY == -3)
                {
                    if (MapItems[x].Transparent == false)
                    {
                        //ADD TO HIDDEN
                        PointToAdd = new Point(MapX - 2, MapY - 4);
                        HiddenList.Add(PointToAdd);
                    }
                }
                //N N N
                else if (MapItems[x].MapX - MapX == -0 && MapItems[x].MapY - MapY == -3)
                {
                    if (MapItems[x].Transparent == false)
                    {
                        //ADD TO HIDDEN
                        PointToAdd = new Point(MapX - 0, MapY - 4);
                        HiddenList.Add(PointToAdd);

                        //Check NW N N
                        for (int y = 0; y < MapItems.Count; y++)
                        {
                            if (MapItems[y].MapX - MapX == -1 && MapItems[y].MapY - MapY == -3)
                            {
                                if (MapItems[y].Transparent == false)
                                {
                                    //ADD TO HIDDEN
                                    PointToAdd = new Point(MapX - 1, MapY - 4);
                                    HiddenList.Add(PointToAdd);
                                }
                                break;
                            }
                        }
                        //CHECK NE N N
                        for (int z = 0; z < MapItems.Count; z++)
                        {
                            if (MapItems[z].MapX - MapX == +1 && MapItems[z].MapY - MapY == -3)
                            {
                                if (MapItems[z].Transparent == false)
                                {
                                    //ADD TO HIDDEN
                                    PointToAdd = new Point(MapX + 1, MapY - 4);
                                    HiddenList.Add(PointToAdd);
                                }
                                break;
                            }
                        }
                    }
                }
                // NE N N
                else if (MapItems[x].MapX - MapX == +1 && MapItems[x].MapY - MapY == -3)
                {
                    if (MapItems[x].Transparent == false)
                    {
                        //ADD TO HIDDEN
                        PointToAdd = new Point(MapX + 2, MapY - 4);
                        HiddenList.Add(PointToAdd);
                    }
                }
                // NE NE N
                else if (MapItems[x].MapX - MapX == +2 && MapItems[x].MapY - MapY == -3)
                {
                    if (MapItems[x].Transparent == false)
                    {
                        //ADD TO HIDDEN
                        PointToAdd = new Point(MapX + 3, MapY - 4);
                        HiddenList.Add(PointToAdd);
                    }
                }
                // NE NE NE
                else if (MapItems[x].MapX - MapX == +3 && MapItems[x].MapY - MapY == -3)
                {
                    if (MapItems[x].Transparent == false)
                    {
                        //ADD TO HIDDEN
                        PointToAdd = new Point(MapX + 4, MapY - 4);
                        HiddenList.Add(PointToAdd);
                    }
                }
                // NE NE E
                else if (MapItems[x].MapX - MapX == +3 && MapItems[x].MapY - MapY == -2)
                {
                    if (MapItems[x].Transparent == false)
                    {
                        //ADD TO HIDDEN
                        PointToAdd = new Point(MapX + 4, MapY - 3);
                        HiddenList.Add(PointToAdd);
                    }
                }
                // NE E E
                else if (MapItems[x].MapX - MapX == +3 && MapItems[x].MapY - MapY == -1)
                {
                    if (MapItems[x].Transparent == false)
                    {
                        //ADD TO HIDDEN
                        PointToAdd = new Point(MapX + 4, MapY - 2);
                        HiddenList.Add(PointToAdd);
                    }
                }
                // E E E
                else if (MapItems[x].MapX - MapX == +3 && MapItems[x].MapY - MapY == -0)
                {
                    if (MapItems[x].Transparent == false)
                    {
                        //ADD TO HIDDEN
                        PointToAdd = new Point(MapX + 4, MapY - 0);
                        HiddenList.Add(PointToAdd);

                        //Check NE E E
                        for (int y = 0; y < MapItems.Count; y++)
                        {
                            if (MapItems[y].MapX - MapX == +3 && MapItems[y].MapY - MapY == -1)
                            {
                                if (MapItems[y].Transparent == false)
                                {
                                    //ADD TO HIDDEN
                                    PointToAdd = new Point(MapX + 4, MapY - 1);
                                    HiddenList.Add(PointToAdd);
                                }
                                break;
                            }
                        }
                        //CHECK SE E E
                        for (int z = 0; z < MapItems.Count; z++)
                        {
                            if (MapItems[z].MapX - MapX == +3 && MapItems[z].MapY - MapY == +1)
                            {
                                if (MapItems[z].Transparent == false)
                                {
                                    //ADD TO HIDDEN
                                    PointToAdd = new Point(MapX + 4, MapY + 1);
                                    HiddenList.Add(PointToAdd);
                                }
                                break;
                            }
                        }
                    }
                }
                //SE E E
                else if (MapItems[x].MapX - MapX == +3 && MapItems[x].MapY - MapY == +1)
                {
                    if (MapItems[x].Transparent == false)
                    {
                        //ADD TO HIDDEN
                        PointToAdd = new Point(MapX + 4, MapY + 2);
                        HiddenList.Add(PointToAdd);
                    }
                }
                //SE SE E
                else if (MapItems[x].MapX - MapX == +3 && MapItems[x].MapY - MapY == +2)
                {
                    if (MapItems[x].Transparent == false)
                    {
                        //ADD TO HIDDEN
                        PointToAdd = new Point(MapX + 4, MapY + 3);
                        HiddenList.Add(PointToAdd);
                    }
                }
                //SE SE SE
                else if (MapItems[x].MapX - MapX == +3 && MapItems[x].MapY - MapY == +3)
                {
                    if (MapItems[x].Transparent == false)
                    {
                        //ADD TO HIDDEN
                        PointToAdd = new Point(MapX + 4, MapY + 4);
                        HiddenList.Add(PointToAdd);
                    }
                }
                //SE SE S
                else if (MapItems[x].MapX - MapX == +2 && MapItems[x].MapY - MapY == +3)
                {
                    if (MapItems[x].Transparent == false)
                    {
                        //ADD TO HIDDEN
                        PointToAdd = new Point(MapX + 3, MapY + 4);
                        HiddenList.Add(PointToAdd);
                    }
                }
                //SE S S
                else if (MapItems[x].MapX - MapX == +1 && MapItems[x].MapY - MapY == +3)
                {
                    if (MapItems[x].Transparent == false)
                    {
                        //ADD TO HIDDEN
                        PointToAdd = new Point(MapX + 2, MapY + 4);
                        HiddenList.Add(PointToAdd);
                    }
                }
                //S S S
                else if (MapItems[x].MapX - MapX == +0 && MapItems[x].MapY - MapY == +3)
                {
                    if (MapItems[x].Transparent == false)
                    {
                        //ADD TO HIDDEN
                        PointToAdd = new Point(MapX + 0, MapY + 4);
                        HiddenList.Add(PointToAdd);

                        //Check SE S S
                        for (int y = 0; y < MapItems.Count; y++)
                        {
                            if (MapItems[y].MapX - MapX == +1 && MapItems[y].MapY - MapY == +3)
                            {
                                if (MapItems[y].Transparent == false)
                                {
                                    //ADD TO HIDDEN
                                    PointToAdd = new Point(MapX + 1, MapY + 4);
                                    HiddenList.Add(PointToAdd);
                                }
                                break;
                            }
                        }
                        //CHECK SE E E
                        for (int z = 0; z < MapItems.Count; z++)
                        {
                            if (MapItems[z].MapX - MapX == -1 && MapItems[z].MapY - MapY == +3)
                            {
                                if (MapItems[z].Transparent == false)
                                {
                                    //ADD TO HIDDEN
                                    PointToAdd = new Point(MapX - 1, MapY + 4);
                                    HiddenList.Add(PointToAdd);
                                }
                                break;
                            }
                        }
                    }
                }
                // SW S S
                else if (MapItems[x].MapX - MapX == -1 && MapItems[x].MapY - MapY == +3)
                {
                    if (MapItems[x].Transparent == false)
                    {
                        //ADD TO HIDDEN
                        PointToAdd = new Point(MapX - 2, MapY + 4);
                        HiddenList.Add(PointToAdd);
                    }
                }
                // SW SW S
                else if (MapItems[x].MapX - MapX == -2 && MapItems[x].MapY - MapY == +3)
                {
                    if (MapItems[x].Transparent == false)
                    {
                        //ADD TO HIDDEN
                        PointToAdd = new Point(MapX - 3, MapY + 4);
                        HiddenList.Add(PointToAdd);
                    }
                }
                // SW SW SW
                else if (MapItems[x].MapX - MapX == -3 && MapItems[x].MapY - MapY == +3)
                {
                    if (MapItems[x].Transparent == false)
                    {
                        //ADD TO HIDDEN
                        PointToAdd = new Point(MapX - 4, MapY + 4);
                        HiddenList.Add(PointToAdd);
                    }
                }
                // SW SW W
                else if (MapItems[x].MapX - MapX == -3 && MapItems[x].MapY - MapY == +2)
                {
                    if (MapItems[x].Transparent == false)
                    {
                        //ADD TO HIDDEN
                        PointToAdd = new Point(MapX - 4, MapY + 3);
                        HiddenList.Add(PointToAdd);
                    }
                }
                // SW W W
                else if (MapItems[x].MapX - MapX == -3 && MapItems[x].MapY - MapY == +1)
                {
                    if (MapItems[x].Transparent == false)
                    {
                        //ADD TO HIDDEN
                        PointToAdd = new Point(MapX - 4, MapY + 2);
                        HiddenList.Add(PointToAdd);
                    }
                }
                // W W W
                else if (MapItems[x].MapX - MapX == -3 && MapItems[x].MapY - MapY == +0)
                {
                    if (MapItems[x].Transparent == false)
                    {
                        //ADD TO HIDDEN
                        PointToAdd = new Point(MapX - 4, MapY + 0);
                        HiddenList.Add(PointToAdd);

                        //Check SW W W
                        for (int y = 0; y < MapItems.Count; y++)
                        {
                            if (MapItems[y].MapX - MapX == -3 && MapItems[y].MapY - MapY == +1)
                            {
                                if (MapItems[y].Transparent == false)
                                {
                                    //ADD TO HIDDEN
                                    PointToAdd = new Point(MapX - 4, MapY + 1);
                                    HiddenList.Add(PointToAdd);
                                }
                                break;
                            }
                        }
                        //CHECK NW W W
                        for (int y = 0; y < MapItems.Count; y++)
                        {
                            if (MapItems[y].MapX - MapX == -3 && MapItems[y].MapY - MapY == -1)
                            {
                                if (MapItems[y].Transparent == false)
                                {
                                    //ADD TO HIDDEN
                                    PointToAdd = new Point(MapX - 4, MapY - 1);
                                    HiddenList.Add(PointToAdd);
                                }
                                break;
                            }
                        }
                    }
                }
                //NW W W
                else if (MapItems[x].MapX - MapX == -3 && MapItems[x].MapY - MapY == -1)
                {
                    if (MapItems[x].Transparent == false)
                    {
                        //ADD TO HIDDEN
                        PointToAdd = new Point(MapX - 4, MapY - 2);
                        HiddenList.Add(PointToAdd);
                    }
                }
                //NW NW W
                else if (MapItems[x].MapX - MapX == -3 && MapItems[x].MapY - MapY == -2)
                {
                    if (MapItems[x].Transparent == false)
                    {
                        //ADD TO HIDDEN
                        PointToAdd = new Point(MapX - 4, MapY - 3);
                        HiddenList.Add(PointToAdd);
                    }
                }
            }
            return HiddenList;
        }

        //Locates Hidden Map points from creatures position
        //TODO: This is terribly written, figure out math to do this rather than hard coding ever senario
        public static List<Point> FindHidden(CreatureBase MyCreature, List<MapItem> CreatureMapItems, bool ignoreDark)
        {
            List<Point> HiddenList = new List<Point>();
            Point PointToAdd = new Point();
            for (int x = 0; x < CreatureMapItems.Count; x++)
            {
                //If this position is dark and this creature does not have NV, then hide the position
                if (ignoreDark == false && CreatureMapItems[x].isDark(MyCreature) && MyCreature.buffManager.HasNightVision() == false)
                    HiddenList.Add(new Point(CreatureMapItems[x].MapX, CreatureMapItems[x].MapY));

                //NW
                if (CreatureMapItems[x].MapX - MyCreature.MapX == -1 && CreatureMapItems[x].MapY - MyCreature.MapY == -1)
                {
                    if (CreatureMapItems[x].Transparent == false || (CreatureMapItems[x].isDark(MyCreature) == true && ignoreDark == false))
                    {
                        //ADD TO HIDDEN
                        PointToAdd = new Point(MyCreature.MapX - 2, MyCreature.MapY - 2);
                        HiddenList.Add(PointToAdd);
                        PointToAdd = new Point(MyCreature.MapX - 2, MyCreature.MapY - 3);
                        HiddenList.Add(PointToAdd);
                        PointToAdd = new Point(MyCreature.MapX - 2, MyCreature.MapY - 4);
                        HiddenList.Add(PointToAdd);

                        PointToAdd = new Point(MyCreature.MapX - 3, MyCreature.MapY - 2);
                        HiddenList.Add(PointToAdd);
                        PointToAdd = new Point(MyCreature.MapX - 3, MyCreature.MapY - 3);
                        HiddenList.Add(PointToAdd);
                        PointToAdd = new Point(MyCreature.MapX - 3, MyCreature.MapY - 4);
                        HiddenList.Add(PointToAdd);

                        PointToAdd = new Point(MyCreature.MapX - 4, MyCreature.MapY - 2);
                        HiddenList.Add(PointToAdd);
                        PointToAdd = new Point(MyCreature.MapX - 4, MyCreature.MapY - 3);
                        HiddenList.Add(PointToAdd);
                        PointToAdd = new Point(MyCreature.MapX - 4, MyCreature.MapY - 4);
                        HiddenList.Add(PointToAdd);
                    }
                }
                //N
                else if (CreatureMapItems[x].MapX - MyCreature.MapX == 0 && CreatureMapItems[x].MapY - MyCreature.MapY == -1)
                {
                    if (CreatureMapItems[x].Transparent == false || (CreatureMapItems[x].isDark(MyCreature) == true && ignoreDark == false))
                    {
                        //ADD TO HIDDEN
                        PointToAdd = new Point(MyCreature.MapX - 0, MyCreature.MapY - 2);
                        HiddenList.Add(PointToAdd);
                        PointToAdd = new Point(MyCreature.MapX - 0, MyCreature.MapY - 3);
                        HiddenList.Add(PointToAdd);
                        PointToAdd = new Point(MyCreature.MapX - 0, MyCreature.MapY - 4);
                        HiddenList.Add(PointToAdd);

                        //Check NW
                        for (int y = 0; y < CreatureMapItems.Count; y++)
                        {
                            if (CreatureMapItems[y].MapX - MyCreature.MapX == -1 && CreatureMapItems[y].MapY - MyCreature.MapY == -1)
                            {
                                if (CreatureMapItems[y].Transparent == false || (CreatureMapItems[y].isDark(MyCreature) == true && ignoreDark == false))
                                {
                                    //ADD TO HIDDEN
                                    PointToAdd = new Point(MyCreature.MapX - 1, MyCreature.MapY - 2);
                                    HiddenList.Add(PointToAdd);
                                    PointToAdd = new Point(MyCreature.MapX - 1, MyCreature.MapY - 3);
                                    HiddenList.Add(PointToAdd);
                                    PointToAdd = new Point(MyCreature.MapX - 2, MyCreature.MapY - 3);
                                    HiddenList.Add(PointToAdd);
                                    PointToAdd = new Point(MyCreature.MapX - 1, MyCreature.MapY - 4);
                                    HiddenList.Add(PointToAdd);
                                    PointToAdd = new Point(MyCreature.MapX - 2, MyCreature.MapY - 4);
                                    HiddenList.Add(PointToAdd);
                                }
                                break;
                            }
                        }
                        //CHECK NE
                        for (int z = 0; z < CreatureMapItems.Count; z++)
                        {
                            if (CreatureMapItems[z].MapX - MyCreature.MapX == 1 && CreatureMapItems[z].MapY - MyCreature.MapY == -1)
                            {
                                if (CreatureMapItems[z].Transparent == false || (CreatureMapItems[z].isDark(MyCreature) == true && ignoreDark == false))
                                {
                                    //ADD TO HIDDEN
                                    PointToAdd = new Point(MyCreature.MapX + 1, MyCreature.MapY - 2);
                                    HiddenList.Add(PointToAdd);
                                    PointToAdd = new Point(MyCreature.MapX + 1, MyCreature.MapY - 3);
                                    HiddenList.Add(PointToAdd);
                                    PointToAdd = new Point(MyCreature.MapX + 2, MyCreature.MapY - 3);
                                    HiddenList.Add(PointToAdd);
                                    PointToAdd = new Point(MyCreature.MapX + 1, MyCreature.MapY - 4);
                                    HiddenList.Add(PointToAdd);
                                    PointToAdd = new Point(MyCreature.MapX + 2, MyCreature.MapY - 4);
                                    HiddenList.Add(PointToAdd);
                                }
                                break;
                            }
                        }
                    }
                }
                //NE
                else if (CreatureMapItems[x].MapX - MyCreature.MapX == 1 && CreatureMapItems[x].MapY - MyCreature.MapY == -1)
                {
                    if (CreatureMapItems[x].Transparent == false || (CreatureMapItems[x].isDark(MyCreature) == true && ignoreDark == false))
                    {
                        //ADD TO HIDDEN
                        PointToAdd = new Point(MyCreature.MapX + 2, MyCreature.MapY - 2);
                        HiddenList.Add(PointToAdd);
                        PointToAdd = new Point(MyCreature.MapX + 2, MyCreature.MapY - 3);
                        HiddenList.Add(PointToAdd);
                        PointToAdd = new Point(MyCreature.MapX + 2, MyCreature.MapY - 4);
                        HiddenList.Add(PointToAdd);

                        PointToAdd = new Point(MyCreature.MapX + 3, MyCreature.MapY - 2);
                        HiddenList.Add(PointToAdd);
                        PointToAdd = new Point(MyCreature.MapX + 3, MyCreature.MapY - 3);
                        HiddenList.Add(PointToAdd);
                        PointToAdd = new Point(MyCreature.MapX + 3, MyCreature.MapY - 4);
                        HiddenList.Add(PointToAdd);

                        PointToAdd = new Point(MyCreature.MapX + 4, MyCreature.MapY - 2);
                        HiddenList.Add(PointToAdd);
                        PointToAdd = new Point(MyCreature.MapX + 4, MyCreature.MapY - 3);
                        HiddenList.Add(PointToAdd);
                        PointToAdd = new Point(MyCreature.MapX + 4, MyCreature.MapY - 4);
                        HiddenList.Add(PointToAdd);
                    }
                }

                //E
                else if (CreatureMapItems[x].MapX - MyCreature.MapX == 1 && CreatureMapItems[x].MapY - MyCreature.MapY == 0)
                {
                    if (CreatureMapItems[x].Transparent == false || (CreatureMapItems[x].isDark(MyCreature) == true && ignoreDark == false))
                    {
                        //ADD TO HIDDEN
                        PointToAdd = new Point(MyCreature.MapX + 2, MyCreature.MapY - 0);
                        HiddenList.Add(PointToAdd);
                        PointToAdd = new Point(MyCreature.MapX + 3, MyCreature.MapY - 0);
                        HiddenList.Add(PointToAdd);
                        PointToAdd = new Point(MyCreature.MapX + 4, MyCreature.MapY - 0);
                        HiddenList.Add(PointToAdd);

                        //Check NE
                        for (int y = 0; y < CreatureMapItems.Count; y++)
                        {
                            if (CreatureMapItems[y].MapX - MyCreature.MapX == 1 && CreatureMapItems[y].MapY - MyCreature.MapY == -1)
                            {
                                if (CreatureMapItems[y].Transparent == false || (CreatureMapItems[y].isDark(MyCreature) == true && ignoreDark == false))
                                {
                                    //ADD TO HIDDEN
                                    PointToAdd = new Point(MyCreature.MapX + 2, MyCreature.MapY - 1);
                                    HiddenList.Add(PointToAdd);
                                    PointToAdd = new Point(MyCreature.MapX + 3, MyCreature.MapY - 1);
                                    HiddenList.Add(PointToAdd);
                                    PointToAdd = new Point(MyCreature.MapX + 3, MyCreature.MapY - 2);
                                    HiddenList.Add(PointToAdd);
                                    PointToAdd = new Point(MyCreature.MapX + 4, MyCreature.MapY - 1);
                                    HiddenList.Add(PointToAdd);
                                    PointToAdd = new Point(MyCreature.MapX + 4, MyCreature.MapY - 2);
                                    HiddenList.Add(PointToAdd);
                                }
                                break;
                            }
                        }
                        //CHECK SE
                        for (int z = 0; z < CreatureMapItems.Count; z++)
                        {
                            if (CreatureMapItems[z].MapX - MyCreature.MapX == 1 && CreatureMapItems[z].MapY - MyCreature.MapY == 1)
                            {
                                if (CreatureMapItems[z].Transparent == false || (CreatureMapItems[z].isDark(MyCreature) == true && ignoreDark == false))
                                {
                                    //ADD TO HIDDEN
                                    PointToAdd = new Point(MyCreature.MapX + 2, MyCreature.MapY + 1);
                                    HiddenList.Add(PointToAdd);
                                    PointToAdd = new Point(MyCreature.MapX + 3, MyCreature.MapY + 1);
                                    HiddenList.Add(PointToAdd);
                                    PointToAdd = new Point(MyCreature.MapX + 3, MyCreature.MapY + 2);
                                    HiddenList.Add(PointToAdd);
                                    PointToAdd = new Point(MyCreature.MapX + 4, MyCreature.MapY + 1);
                                    HiddenList.Add(PointToAdd);
                                    PointToAdd = new Point(MyCreature.MapX + 4, MyCreature.MapY + 2);
                                    HiddenList.Add(PointToAdd);
                                }
                                break;
                            }
                        }
                    }
                }
                //SE
                else if (CreatureMapItems[x].MapX - MyCreature.MapX == 1 && CreatureMapItems[x].MapY - MyCreature.MapY == 1)
                {
                    if (CreatureMapItems[x].Transparent == false || (CreatureMapItems[x].isDark(MyCreature) == true && ignoreDark == false))
                    {
                        //ADD TO HIDDEN
                        PointToAdd = new Point(MyCreature.MapX + 2, MyCreature.MapY + 2);
                        HiddenList.Add(PointToAdd);
                        PointToAdd = new Point(MyCreature.MapX + 2, MyCreature.MapY + 3);
                        HiddenList.Add(PointToAdd);
                        PointToAdd = new Point(MyCreature.MapX + 2, MyCreature.MapY + 4);
                        HiddenList.Add(PointToAdd);

                        PointToAdd = new Point(MyCreature.MapX + 3, MyCreature.MapY + 2);
                        HiddenList.Add(PointToAdd);
                        PointToAdd = new Point(MyCreature.MapX + 3, MyCreature.MapY + 3);
                        HiddenList.Add(PointToAdd);
                        PointToAdd = new Point(MyCreature.MapX + 3, MyCreature.MapY + 4);
                        HiddenList.Add(PointToAdd);

                        PointToAdd = new Point(MyCreature.MapX + 4, MyCreature.MapY + 2);
                        HiddenList.Add(PointToAdd);
                        PointToAdd = new Point(MyCreature.MapX + 4, MyCreature.MapY + 3);
                        HiddenList.Add(PointToAdd);
                        PointToAdd = new Point(MyCreature.MapX + 4, MyCreature.MapY + 4);
                        HiddenList.Add(PointToAdd);
                    }
                }
                //S
                else if (CreatureMapItems[x].MapX - MyCreature.MapX == 0 && CreatureMapItems[x].MapY - MyCreature.MapY == 1)
                {
                    if (CreatureMapItems[x].Transparent == false || (CreatureMapItems[x].isDark(MyCreature) == true && ignoreDark == false))
                    {
                        //ADD TO HIDDEN
                        PointToAdd = new Point(MyCreature.MapX + 0, MyCreature.MapY + 2);
                        HiddenList.Add(PointToAdd);
                        PointToAdd = new Point(MyCreature.MapX + 0, MyCreature.MapY + 3);
                        HiddenList.Add(PointToAdd);
                        PointToAdd = new Point(MyCreature.MapX + 0, MyCreature.MapY + 4);
                        HiddenList.Add(PointToAdd);

                        //Check SE
                        for (int y = 0; y < CreatureMapItems.Count; y++)
                        {
                            if (CreatureMapItems[y].MapX - MyCreature.MapX == 1 && CreatureMapItems[y].MapY - MyCreature.MapY == 1)
                            {
                                if (CreatureMapItems[y].Transparent == false || (CreatureMapItems[y].isDark(MyCreature) == true && ignoreDark == false))
                                {
                                    //ADD TO HIDDEN
                                    PointToAdd = new Point(MyCreature.MapX + 1, MyCreature.MapY + 2);
                                    HiddenList.Add(PointToAdd);
                                    PointToAdd = new Point(MyCreature.MapX + 1, MyCreature.MapY + 3);
                                    HiddenList.Add(PointToAdd);
                                    PointToAdd = new Point(MyCreature.MapX + 2, MyCreature.MapY + 3);
                                    HiddenList.Add(PointToAdd);
                                    PointToAdd = new Point(MyCreature.MapX + 1, MyCreature.MapY + 4);
                                    HiddenList.Add(PointToAdd);
                                    PointToAdd = new Point(MyCreature.MapX + 2, MyCreature.MapY + 4);
                                    HiddenList.Add(PointToAdd);
                                }
                                break;
                            }
                        }
                        //CHECK SW
                        for (int z = 0; z < CreatureMapItems.Count; z++)
                        {
                            if (CreatureMapItems[z].MapX - MyCreature.MapX == -1 && CreatureMapItems[z].MapY - MyCreature.MapY == 1)
                            {
                                if (CreatureMapItems[z].Transparent == false || (CreatureMapItems[z].isDark(MyCreature) == true && ignoreDark == false))
                                {
                                    //ADD TO HIDDEN
                                    PointToAdd = new Point(MyCreature.MapX - 1, MyCreature.MapY + 2);
                                    HiddenList.Add(PointToAdd);
                                    PointToAdd = new Point(MyCreature.MapX - 1, MyCreature.MapY + 3);
                                    HiddenList.Add(PointToAdd);
                                    PointToAdd = new Point(MyCreature.MapX - 2, MyCreature.MapY + 3);
                                    HiddenList.Add(PointToAdd);
                                    PointToAdd = new Point(MyCreature.MapX - 1, MyCreature.MapY + 4);
                                    HiddenList.Add(PointToAdd);
                                    PointToAdd = new Point(MyCreature.MapX - 2, MyCreature.MapY + 4);
                                    HiddenList.Add(PointToAdd);
                                }
                                break;
                            }
                        }
                    }
                }
                //SW
                else if (CreatureMapItems[x].MapX - MyCreature.MapX == -1 && CreatureMapItems[x].MapY - MyCreature.MapY == 1)
                {
                    if (CreatureMapItems[x].Transparent == false || (CreatureMapItems[x].isDark(MyCreature) == true && ignoreDark == false))
                    {
                        //ADD TO HIDDEN
                        PointToAdd = new Point(MyCreature.MapX - 2, MyCreature.MapY + 2);
                        HiddenList.Add(PointToAdd);
                        PointToAdd = new Point(MyCreature.MapX - 2, MyCreature.MapY + 3);
                        HiddenList.Add(PointToAdd);
                        PointToAdd = new Point(MyCreature.MapX - 2, MyCreature.MapY + 4);
                        HiddenList.Add(PointToAdd);

                        PointToAdd = new Point(MyCreature.MapX - 3, MyCreature.MapY + 2);
                        HiddenList.Add(PointToAdd);
                        PointToAdd = new Point(MyCreature.MapX - 3, MyCreature.MapY + 3);
                        HiddenList.Add(PointToAdd);
                        PointToAdd = new Point(MyCreature.MapX - 3, MyCreature.MapY + 4);
                        HiddenList.Add(PointToAdd);

                        PointToAdd = new Point(MyCreature.MapX - 4, MyCreature.MapY + 2);
                        HiddenList.Add(PointToAdd);
                        PointToAdd = new Point(MyCreature.MapX - 4, MyCreature.MapY + 3);
                        HiddenList.Add(PointToAdd);
                        PointToAdd = new Point(MyCreature.MapX - 4, MyCreature.MapY + 4);
                        HiddenList.Add(PointToAdd);
                    }
                }
                //W
                else if (CreatureMapItems[x].MapX - MyCreature.MapX == -1 && CreatureMapItems[x].MapY - MyCreature.MapY == 0)
                {
                    if (CreatureMapItems[x].Transparent == false || (CreatureMapItems[x].isDark(MyCreature) == true && ignoreDark == false))
                    {
                        //ADD TO HIDDEN
                        PointToAdd = new Point(MyCreature.MapX - 2, MyCreature.MapY + 0);
                        HiddenList.Add(PointToAdd);
                        PointToAdd = new Point(MyCreature.MapX - 3, MyCreature.MapY + 0);
                        HiddenList.Add(PointToAdd);
                        PointToAdd = new Point(MyCreature.MapX - 4, MyCreature.MapY + 0);
                        HiddenList.Add(PointToAdd);

                        //Check SW
                        for (int y = 0; y < CreatureMapItems.Count; y++)
                        {
                            if (CreatureMapItems[y].MapX - MyCreature.MapX == -1 && CreatureMapItems[y].MapY - MyCreature.MapY == 1)
                            {
                                if (CreatureMapItems[y].Transparent == false || (CreatureMapItems[y].isDark(MyCreature) == true && ignoreDark == false))
                                {
                                    //ADD TO HIDDEN
                                    PointToAdd = new Point(MyCreature.MapX - 2, MyCreature.MapY + 1);
                                    HiddenList.Add(PointToAdd);
                                    PointToAdd = new Point(MyCreature.MapX - 3, MyCreature.MapY + 1);
                                    HiddenList.Add(PointToAdd);
                                    PointToAdd = new Point(MyCreature.MapX - 3, MyCreature.MapY + 2);
                                    HiddenList.Add(PointToAdd);
                                    PointToAdd = new Point(MyCreature.MapX - 4, MyCreature.MapY + 1);
                                    HiddenList.Add(PointToAdd);
                                    PointToAdd = new Point(MyCreature.MapX - 4, MyCreature.MapY + 2);
                                    HiddenList.Add(PointToAdd);
                                }
                                break;
                            }
                        }
                        //CHECK NW
                        for (int z = 0; z < CreatureMapItems.Count; z++)
                        {
                            if (CreatureMapItems[z].MapX - MyCreature.MapX == -1 && CreatureMapItems[z].MapY - MyCreature.MapY == -1)
                            {
                                if (CreatureMapItems[z].Transparent == false || (CreatureMapItems[z].isDark(MyCreature) == true && ignoreDark == false))
                                {
                                    //ADD TO HIDDEN
                                    PointToAdd = new Point(MyCreature.MapX - 2, MyCreature.MapY - 1);
                                    HiddenList.Add(PointToAdd);
                                    PointToAdd = new Point(MyCreature.MapX - 3, MyCreature.MapY - 1);
                                    HiddenList.Add(PointToAdd);
                                    PointToAdd = new Point(MyCreature.MapX - 3, MyCreature.MapY - 2);
                                    HiddenList.Add(PointToAdd);
                                    PointToAdd = new Point(MyCreature.MapX - 4, MyCreature.MapY - 1);
                                    HiddenList.Add(PointToAdd);
                                    PointToAdd = new Point(MyCreature.MapX - 4, MyCreature.MapY - 2);
                                    HiddenList.Add(PointToAdd);
                                }
                                break;
                            }
                        }
                    }
                }
                /////////////////////////////////////////////////////

                //NW NW
                else if (CreatureMapItems[x].MapX - MyCreature.MapX == -2 && CreatureMapItems[x].MapY - MyCreature.MapY == -2)
                {
                    if (CreatureMapItems[x].Transparent == false || (CreatureMapItems[x].isDark(MyCreature) == true && ignoreDark == false))
                    {
                        //ADD TO HIDDEN
                        PointToAdd = new Point(MyCreature.MapX - 3, MyCreature.MapY - 3);
                        HiddenList.Add(PointToAdd);
                        PointToAdd = new Point(MyCreature.MapX - 4, MyCreature.MapY - 4);
                        HiddenList.Add(PointToAdd);
			            PointToAdd = new Point(MyCreature.MapX - 3, MyCreature.MapY - 4);
                        HiddenList.Add(PointToAdd);
                        PointToAdd = new Point(MyCreature.MapX - 4, MyCreature.MapY - 3);
                        HiddenList.Add(PointToAdd);
                    }
                }
                //NW N
                else if (CreatureMapItems[x].MapX - MyCreature.MapX == -1 && CreatureMapItems[x].MapY - MyCreature.MapY == -2)
                {
                    if (CreatureMapItems[x].Transparent == false || (CreatureMapItems[x].isDark(MyCreature) == true && ignoreDark == false))
                    {
                        //ADD TO HIDDEN
                        PointToAdd = new Point(MyCreature.MapX - 2, MyCreature.MapY - 3);
                        HiddenList.Add(PointToAdd);
                        PointToAdd = new Point(MyCreature.MapX - 2, MyCreature.MapY - 4);
                        HiddenList.Add(PointToAdd);
                        PointToAdd = new Point(MyCreature.MapX - 3, MyCreature.MapY - 4);
                        HiddenList.Add(PointToAdd);
                    }
                }
                //N N
                else if (CreatureMapItems[x].MapX - MyCreature.MapX == -0 && CreatureMapItems[x].MapY - MyCreature.MapY == -2)
                {
                    if (CreatureMapItems[x].Transparent == false || (CreatureMapItems[x].isDark(MyCreature) == true && ignoreDark == false))
                    {
                        //ADD TO HIDDEN
                        PointToAdd = new Point(MyCreature.MapX - 0, MyCreature.MapY - 3);
                        HiddenList.Add(PointToAdd);
                        PointToAdd = new Point(MyCreature.MapX - 0, MyCreature.MapY - 4);
                        HiddenList.Add(PointToAdd);
			
                        //Check WN N
                        for (int y = 0; y < CreatureMapItems.Count; y++)
                        {
                            if (CreatureMapItems[y].MapX - MyCreature.MapX == -1 && CreatureMapItems[y].MapY - MyCreature.MapY == -2)
                            {
                                if (CreatureMapItems[y].Transparent == false || (CreatureMapItems[y].isDark(MyCreature) == true && ignoreDark == false))
                                {
                                    //ADD TO HIDDEN
                                    PointToAdd = new Point(MyCreature.MapX - 1, MyCreature.MapY - 3);
                                    HiddenList.Add(PointToAdd);
                                    PointToAdd = new Point(MyCreature.MapX - 1, MyCreature.MapY - 4);
                                    HiddenList.Add(PointToAdd);
				
                                }
                                break;
                            }
                        }
                        //CHECK NE N
                        for (int z = 0; z < CreatureMapItems.Count; z++)
                        {
                            if (CreatureMapItems[z].MapX - MyCreature.MapX == +1 && CreatureMapItems[z].MapY - MyCreature.MapY == -2)
                            {
                                if (CreatureMapItems[z].Transparent == false || (CreatureMapItems[z].isDark(MyCreature) == true && ignoreDark == false))
                                {
                                    //ADD TO HIDDEN
                                    PointToAdd = new Point(MyCreature.MapX + 1, MyCreature.MapY - 3);
                                    HiddenList.Add(PointToAdd);
                                    PointToAdd = new Point(MyCreature.MapX + 1, MyCreature.MapY - 4);
                                    HiddenList.Add(PointToAdd);
                                }
                                break;
                            }
                        }
                    }
                }
                //NE N
                else if (CreatureMapItems[x].MapX - MyCreature.MapX == +1 && CreatureMapItems[x].MapY - MyCreature.MapY == -2)
                {
                    if (CreatureMapItems[x].Transparent == false || (CreatureMapItems[x].isDark(MyCreature) == true && ignoreDark == false))
                    {
                        //ADD TO HIDDEN
                        PointToAdd = new Point(MyCreature.MapX + 2, MyCreature.MapY - 3);
                        HiddenList.Add(PointToAdd);
                        PointToAdd = new Point(MyCreature.MapX + 2, MyCreature.MapY - 4);
                        HiddenList.Add(PointToAdd);
                        PointToAdd = new Point(MyCreature.MapX + 3, MyCreature.MapY - 4);
                        HiddenList.Add(PointToAdd);

                    }
                }
                //NE NE
                else if (CreatureMapItems[x].MapX - MyCreature.MapX == +2 && CreatureMapItems[x].MapY - MyCreature.MapY == -2)
                {
                    if (CreatureMapItems[x].Transparent == false || (CreatureMapItems[x].isDark(MyCreature) == true && ignoreDark == false))
                    {
                        //ADD TO HIDDEN
                        PointToAdd = new Point(MyCreature.MapX + 3, MyCreature.MapY - 3);
                        HiddenList.Add(PointToAdd);
                        PointToAdd = new Point(MyCreature.MapX + 4, MyCreature.MapY - 4);
                        HiddenList.Add(PointToAdd);
 			            PointToAdd = new Point(MyCreature.MapX + 3, MyCreature.MapY - 4);
                        HiddenList.Add(PointToAdd);
                        PointToAdd = new Point(MyCreature.MapX + 4, MyCreature.MapY - 3);
                        HiddenList.Add(PointToAdd);
                    }
                }
                //NE E
                else if (CreatureMapItems[x].MapX - MyCreature.MapX == +2 && CreatureMapItems[x].MapY - MyCreature.MapY == -1)
                {
                    if (CreatureMapItems[x].Transparent == false || (CreatureMapItems[x].isDark(MyCreature) == true && ignoreDark == false))
                    {
                        //ADD TO HIDDEN
                        PointToAdd = new Point(MyCreature.MapX + 3, MyCreature.MapY - 2);
                        HiddenList.Add(PointToAdd);
                        PointToAdd = new Point(MyCreature.MapX + 4, MyCreature.MapY - 2);
                        HiddenList.Add(PointToAdd);
                        PointToAdd = new Point(MyCreature.MapX + 4, MyCreature.MapY - 3);
                        HiddenList.Add(PointToAdd);
                    }
                }
                //E E
                else if (CreatureMapItems[x].MapX - MyCreature.MapX == +2 && CreatureMapItems[x].MapY - MyCreature.MapY == -0)
                {
                    if (CreatureMapItems[x].Transparent == false || (CreatureMapItems[x].isDark(MyCreature) == true && ignoreDark == false))
                    {
                        //ADD TO HIDDEN
                        PointToAdd = new Point(MyCreature.MapX + 3, MyCreature.MapY + 0);
                        HiddenList.Add(PointToAdd);
                        PointToAdd = new Point(MyCreature.MapX + 4, MyCreature.MapY + 0);
                        HiddenList.Add(PointToAdd);

                        //Check NE E
                        for (int y = 0; y < CreatureMapItems.Count; y++)
                        {
                            if (CreatureMapItems[y].MapX - MyCreature.MapX == +2 && CreatureMapItems[y].MapY - MyCreature.MapY == -1)
                            {
                                if (CreatureMapItems[y].Transparent == false || (CreatureMapItems[y].isDark(MyCreature) == true && ignoreDark == false))
                                {
                                    //ADD TO HIDDEN
                                    PointToAdd = new Point(MyCreature.MapX + 3, MyCreature.MapY - 1);
                                    HiddenList.Add(PointToAdd);
                                    PointToAdd = new Point(MyCreature.MapX + 4, MyCreature.MapY - 1);
                                    HiddenList.Add(PointToAdd);
                                    PointToAdd = new Point(MyCreature.MapX + 4, MyCreature.MapY - 2);
                                    HiddenList.Add(PointToAdd);
                                }
                                break;
                            }
                        }
                        //CHECK SE N
                        for (int z = 0; z < CreatureMapItems.Count; z++)
                        {
                            if (CreatureMapItems[z].MapX - MyCreature.MapX == +2 && CreatureMapItems[z].MapY - MyCreature.MapY == +1)
                            {
                                if (CreatureMapItems[z].Transparent == false || (CreatureMapItems[z].isDark(MyCreature) == true && ignoreDark == false))
                                {
                                    //ADD TO HIDDEN
                                    PointToAdd = new Point(MyCreature.MapX + 3, MyCreature.MapY + 1);
                                    HiddenList.Add(PointToAdd);
                                    PointToAdd = new Point(MyCreature.MapX + 4, MyCreature.MapY + 1);
                                    HiddenList.Add(PointToAdd);
                                    PointToAdd = new Point(MyCreature.MapX + 4, MyCreature.MapY + 2);
                                    HiddenList.Add(PointToAdd);
                                }
                                break;
                            }
                        }
                    }
                }
                //SE E
                else if (CreatureMapItems[x].MapX - MyCreature.MapX == +2 && CreatureMapItems[x].MapY - MyCreature.MapY == +1)
                {
                    if (CreatureMapItems[x].Transparent == false || (CreatureMapItems[x].isDark(MyCreature) == true && ignoreDark == false))
                    {
                        //ADD TO HIDDEN
                        PointToAdd = new Point(MyCreature.MapX + 3, MyCreature.MapY + 2);
                        HiddenList.Add(PointToAdd);
                        PointToAdd = new Point(MyCreature.MapX + 4, MyCreature.MapY + 2);
                        HiddenList.Add(PointToAdd);
                        PointToAdd = new Point(MyCreature.MapX + 4, MyCreature.MapY + 3);
                        HiddenList.Add(PointToAdd);
                    }
                }
                //SE SE
                else if (CreatureMapItems[x].MapX - MyCreature.MapX == +2 && CreatureMapItems[x].MapY - MyCreature.MapY == +2)
                {
                    if (CreatureMapItems[x].Transparent == false || (CreatureMapItems[x].isDark(MyCreature) == true && ignoreDark == false))
                    {
                        //ADD TO HIDDEN
                        PointToAdd = new Point(MyCreature.MapX + 3, MyCreature.MapY + 3);
                        HiddenList.Add(PointToAdd);
                        PointToAdd = new Point(MyCreature.MapX + 4, MyCreature.MapY + 4);
                        HiddenList.Add(PointToAdd);
			            PointToAdd = new Point(MyCreature.MapX + 3, MyCreature.MapY + 4);
                        HiddenList.Add(PointToAdd);
                        PointToAdd = new Point(MyCreature.MapX + 4, MyCreature.MapY + 3);
                        HiddenList.Add(PointToAdd);
                    }
                }
                //SE S
                else if (CreatureMapItems[x].MapX - MyCreature.MapX == +1 && CreatureMapItems[x].MapY - MyCreature.MapY == +2)
                {
                    if (CreatureMapItems[x].Transparent == false || (CreatureMapItems[x].isDark(MyCreature) == true && ignoreDark == false))
                    {
                        //ADD TO HIDDEN
                        PointToAdd = new Point(MyCreature.MapX + 2, MyCreature.MapY + 3);
                        HiddenList.Add(PointToAdd);
                        PointToAdd = new Point(MyCreature.MapX + 2, MyCreature.MapY + 4);
                        HiddenList.Add(PointToAdd);
                        PointToAdd = new Point(MyCreature.MapX + 3, MyCreature.MapY + 4);
                        HiddenList.Add(PointToAdd);
                    }
                }
                //S S  
                else if (CreatureMapItems[x].MapX - MyCreature.MapX == +0 && CreatureMapItems[x].MapY - MyCreature.MapY == +2)
                {
                    if (CreatureMapItems[x].Transparent == false || (CreatureMapItems[x].isDark(MyCreature) == true && ignoreDark == false))
                    {
                        //ADD TO HIDDEN
                        PointToAdd = new Point(MyCreature.MapX + 0, MyCreature.MapY + 3);
                        HiddenList.Add(PointToAdd);
                        PointToAdd = new Point(MyCreature.MapX + 0, MyCreature.MapY + 4);
                        HiddenList.Add(PointToAdd);

                        //Check SE E
                        for (int y = 0; y < CreatureMapItems.Count; y++)
                        {
                            if (CreatureMapItems[y].MapX - MyCreature.MapX == +1 && CreatureMapItems[y].MapY - MyCreature.MapY == +2)
                            {
                                if (CreatureMapItems[y].Transparent == false || (CreatureMapItems[y].isDark(MyCreature) == true && ignoreDark == false))
                                {
                                    //ADD TO HIDDEN
                                    PointToAdd = new Point(MyCreature.MapX + 1, MyCreature.MapY + 3);
                                    HiddenList.Add(PointToAdd);
                                    PointToAdd = new Point(MyCreature.MapX + 1, MyCreature.MapY + 4);
                                    HiddenList.Add(PointToAdd);
                                    PointToAdd = new Point(MyCreature.MapX + 2, MyCreature.MapY + 4);
                                    HiddenList.Add(PointToAdd);
                                }
                                break;
                            }
                        }
                        //CHECK SW S
                        for (int z = 0; z < CreatureMapItems.Count; z++)
                        {
                            if (CreatureMapItems[z].MapX - MyCreature.MapX == -1 && CreatureMapItems[z].MapY - MyCreature.MapY == +2)
                            {
                                if (CreatureMapItems[z].Transparent == false || (CreatureMapItems[z].isDark(MyCreature) == true && ignoreDark == false))
                                {
                                    //ADD TO HIDDEN
                                    PointToAdd = new Point(MyCreature.MapX - 1, MyCreature.MapY + 3);
                                    HiddenList.Add(PointToAdd);
                                    PointToAdd = new Point(MyCreature.MapX - 1, MyCreature.MapY + 4);
                                    HiddenList.Add(PointToAdd);
                                    PointToAdd = new Point(MyCreature.MapX - 2, MyCreature.MapY + 4);
                                    HiddenList.Add(PointToAdd);
                                }
                                break;
                            }
                        }
                    }
                }
                //SW S
                else if (CreatureMapItems[x].MapX - MyCreature.MapX == -1 && CreatureMapItems[x].MapY - MyCreature.MapY == +2)
                {
                    if (CreatureMapItems[x].Transparent == false || (CreatureMapItems[x].isDark(MyCreature) == true && ignoreDark == false))
                    {
                        //ADD TO HIDDEN
                        PointToAdd = new Point(MyCreature.MapX - 2, MyCreature.MapY + 3);
                        HiddenList.Add(PointToAdd);
                        PointToAdd = new Point(MyCreature.MapX - 3, MyCreature.MapY + 4);
                        HiddenList.Add(PointToAdd);
                        PointToAdd = new Point(MyCreature.MapX - 2, MyCreature.MapY + 4);
                        HiddenList.Add(PointToAdd);
                    }
                }
                //SW SW
                else if (CreatureMapItems[x].MapX - MyCreature.MapX == -2 && CreatureMapItems[x].MapY - MyCreature.MapY == +2)
                {
                    if (CreatureMapItems[x].Transparent == false || (CreatureMapItems[x].isDark(MyCreature) == true && ignoreDark == false))
                    {
                        //ADD TO HIDDEN
                        PointToAdd = new Point(MyCreature.MapX - 3, MyCreature.MapY + 3);
                        HiddenList.Add(PointToAdd);
                        PointToAdd = new Point(MyCreature.MapX - 4, MyCreature.MapY + 4);
                        HiddenList.Add(PointToAdd);
 			            PointToAdd = new Point(MyCreature.MapX - 3, MyCreature.MapY + 4);
                        HiddenList.Add(PointToAdd);
                        PointToAdd = new Point(MyCreature.MapX - 4, MyCreature.MapY + 3);
                        HiddenList.Add(PointToAdd);
                    }
                }
                //SW W
                else if (CreatureMapItems[x].MapX - MyCreature.MapX == -2 && CreatureMapItems[x].MapY - MyCreature.MapY == +1)
                {
                    if (CreatureMapItems[x].Transparent == false || (CreatureMapItems[x].isDark(MyCreature) == true && ignoreDark == false))
                    {
                        //ADD TO HIDDEN
                        PointToAdd = new Point(MyCreature.MapX - 3, MyCreature.MapY + 2);
                        HiddenList.Add(PointToAdd);
                        PointToAdd = new Point(MyCreature.MapX - 4, MyCreature.MapY + 2);
                        HiddenList.Add(PointToAdd);
                        PointToAdd = new Point(MyCreature.MapX - 4, MyCreature.MapY + 3);
                        HiddenList.Add(PointToAdd);
                    }
                }
                //W W
                else if (CreatureMapItems[x].MapX - MyCreature.MapX == -2 && CreatureMapItems[x].MapY - MyCreature.MapY == +0)
                {
                    if (CreatureMapItems[x].Transparent == false || (CreatureMapItems[x].isDark(MyCreature) == true && ignoreDark == false))
                    {
                        //ADD TO HIDDEN
                        PointToAdd = new Point(MyCreature.MapX - 3, MyCreature.MapY + 0);
                        HiddenList.Add(PointToAdd);
                        PointToAdd = new Point(MyCreature.MapX - 4, MyCreature.MapY + 0);
                        HiddenList.Add(PointToAdd);

                        //Check SW W
                        for (int y = 0; y < CreatureMapItems.Count; y++)
                        {
                            if (CreatureMapItems[y].MapX - MyCreature.MapX == -2 && CreatureMapItems[y].MapY - MyCreature.MapY == +1)
                            {
                                if (CreatureMapItems[y].Transparent == false || (CreatureMapItems[y].isDark(MyCreature) == true && ignoreDark == false))
                                {
                                    //ADD TO HIDDEN
                                    PointToAdd = new Point(MyCreature.MapX - 3, MyCreature.MapY + 1);
                                    HiddenList.Add(PointToAdd);
                                    PointToAdd = new Point(MyCreature.MapX - 4, MyCreature.MapY + 1);
                                    HiddenList.Add(PointToAdd);
                                    PointToAdd = new Point(MyCreature.MapX - 4, MyCreature.MapY + 2);
                                    HiddenList.Add(PointToAdd);
                                }
                                break;
                            }
                        }
                        //CHECK NW W
                        for (int z = 0; z < CreatureMapItems.Count; z++)
                        {
                            if (CreatureMapItems[z].MapX - MyCreature.MapX == -2 && CreatureMapItems[z].MapY - MyCreature.MapY == -1)
                            {
                                if (CreatureMapItems[z].Transparent == false || (CreatureMapItems[z].isDark(MyCreature) == true && ignoreDark == false))
                                {
                                    //ADD TO HIDDEN
                                    PointToAdd = new Point(MyCreature.MapX - 3, MyCreature.MapY - 1);
                                    HiddenList.Add(PointToAdd);
                                    PointToAdd = new Point(MyCreature.MapX - 4, MyCreature.MapY - 1);
                                    HiddenList.Add(PointToAdd);
                                    PointToAdd = new Point(MyCreature.MapX - 4, MyCreature.MapY - 2);
                                    HiddenList.Add(PointToAdd);
                                }
                                break;
                            }
                        }
                    }
                }
                //W NW
                else if (CreatureMapItems[x].MapX - MyCreature.MapX == -2 && CreatureMapItems[x].MapY - MyCreature.MapY == -1)
                {
                    if (CreatureMapItems[x].Transparent == false || (CreatureMapItems[x].isDark(MyCreature) == true && ignoreDark == false))
                    {
                        //ADD TO HIDDEN
                        PointToAdd = new Point(MyCreature.MapX - 3, MyCreature.MapY - 2);
                        HiddenList.Add(PointToAdd);
                        PointToAdd = new Point(MyCreature.MapX - 4, MyCreature.MapY - 2);
                        HiddenList.Add(PointToAdd);
                        PointToAdd = new Point(MyCreature.MapX - 4, MyCreature.MapY - 3);
                        HiddenList.Add(PointToAdd);
                    }
                }
                //////////////////////////////////////////////////////////////

                //NW NW NW
                else if (CreatureMapItems[x].MapX - MyCreature.MapX == -3 && CreatureMapItems[x].MapY - MyCreature.MapY == -3)
                {
                    if (CreatureMapItems[x].Transparent == false || (CreatureMapItems[x].isDark(MyCreature) == true && ignoreDark == false))
                    {
                        //ADD TO HIDDEN
                        PointToAdd = new Point(MyCreature.MapX - 4, MyCreature.MapY - 4);
                        HiddenList.Add(PointToAdd);
                    }
                }
                //NW NW N
                else if (CreatureMapItems[x].MapX - MyCreature.MapX == -2 && CreatureMapItems[x].MapY - MyCreature.MapY == -3)
                {
                    if (CreatureMapItems[x].Transparent == false || (CreatureMapItems[x].isDark(MyCreature) == true && ignoreDark == false))
                    {
                        //ADD TO HIDDEN
                        PointToAdd = new Point(MyCreature.MapX - 3, MyCreature.MapY - 4);
                        HiddenList.Add(PointToAdd);
                    }
                }
                //NW N N
                else if (CreatureMapItems[x].MapX - MyCreature.MapX == -1 && CreatureMapItems[x].MapY - MyCreature.MapY == -3)
                {
                    if (CreatureMapItems[x].Transparent == false || (CreatureMapItems[x].isDark(MyCreature) == true && ignoreDark == false))
                    {
                        //ADD TO HIDDEN
                        PointToAdd = new Point(MyCreature.MapX - 2, MyCreature.MapY - 4);
                        HiddenList.Add(PointToAdd);
                    }
                }
                //N N N
                else if (CreatureMapItems[x].MapX - MyCreature.MapX == -0 && CreatureMapItems[x].MapY - MyCreature.MapY == -3)
                {
                    if (CreatureMapItems[x].Transparent == false || (CreatureMapItems[x].isDark(MyCreature) == true && ignoreDark == false))
                    {
                        //ADD TO HIDDEN
                        PointToAdd = new Point(MyCreature.MapX - 0, MyCreature.MapY - 4);
                        HiddenList.Add(PointToAdd);

                        //Check NW N N
                        for (int y = 0; y < CreatureMapItems.Count; y++)
                        {
                            if (CreatureMapItems[y].MapX - MyCreature.MapX == -1 && CreatureMapItems[y].MapY - MyCreature.MapY == -3)
                            {
                                if (CreatureMapItems[y].Transparent == false || (CreatureMapItems[y].isDark(MyCreature) == true && ignoreDark == false))
                                {
                                    //ADD TO HIDDEN
                                    PointToAdd = new Point(MyCreature.MapX - 1, MyCreature.MapY - 4);
                                    HiddenList.Add(PointToAdd);
                                }
                                break;
                            }
                        }
                        //CHECK NE N N
                        for (int z = 0; z < CreatureMapItems.Count; z++)
                        {
                            if (CreatureMapItems[z].MapX - MyCreature.MapX == +1 && CreatureMapItems[z].MapY - MyCreature.MapY == -3)
                            {
                                if (CreatureMapItems[z].Transparent == false || (CreatureMapItems[z].isDark(MyCreature) == true && ignoreDark == false))
                                {
                                    //ADD TO HIDDEN
                                    PointToAdd = new Point(MyCreature.MapX + 1, MyCreature.MapY - 4);
                                    HiddenList.Add(PointToAdd);
                                }
                                break;
                            }
                        }
                    }
                }
                // NE N N
                else if (CreatureMapItems[x].MapX - MyCreature.MapX == +1 && CreatureMapItems[x].MapY - MyCreature.MapY == -3)
                {
                    if (CreatureMapItems[x].Transparent == false || (CreatureMapItems[x].isDark(MyCreature) == true && ignoreDark == false))
                    {
                        //ADD TO HIDDEN
                        PointToAdd = new Point(MyCreature.MapX + 2, MyCreature.MapY - 4);
                        HiddenList.Add(PointToAdd);
                    }
                }
                // NE NE N
                else if (CreatureMapItems[x].MapX - MyCreature.MapX == +2 && CreatureMapItems[x].MapY - MyCreature.MapY == -3)
                {
                    if (CreatureMapItems[x].Transparent == false || (CreatureMapItems[x].isDark(MyCreature) == true && ignoreDark == false))
                    {
                        //ADD TO HIDDEN
                        PointToAdd = new Point(MyCreature.MapX + 3, MyCreature.MapY - 4);
                        HiddenList.Add(PointToAdd);
                    }
                }
                // NE NE NE
                else if (CreatureMapItems[x].MapX - MyCreature.MapX == +3 && CreatureMapItems[x].MapY - MyCreature.MapY == -3)
                {
                    if (CreatureMapItems[x].Transparent == false || (CreatureMapItems[x].isDark(MyCreature) == true && ignoreDark == false))
                    {
                        //ADD TO HIDDEN
                        PointToAdd = new Point(MyCreature.MapX + 4, MyCreature.MapY - 4);
                        HiddenList.Add(PointToAdd);
                    }
                }
                // NE NE E
                else if (CreatureMapItems[x].MapX - MyCreature.MapX == +3 && CreatureMapItems[x].MapY - MyCreature.MapY == -2)
                {
                    if (CreatureMapItems[x].Transparent == false || (CreatureMapItems[x].isDark(MyCreature) == true && ignoreDark == false))
                    {
                        //ADD TO HIDDEN
                        PointToAdd = new Point(MyCreature.MapX + 4, MyCreature.MapY - 3);
                        HiddenList.Add(PointToAdd);
                    }
                }
                // NE E E
                else if (CreatureMapItems[x].MapX - MyCreature.MapX == +3 && CreatureMapItems[x].MapY - MyCreature.MapY == -1)
                {
                    if (CreatureMapItems[x].Transparent == false || (CreatureMapItems[x].isDark(MyCreature) == true && ignoreDark == false))
                    {
                        //ADD TO HIDDEN
                        PointToAdd = new Point(MyCreature.MapX + 4, MyCreature.MapY - 2);
                        HiddenList.Add(PointToAdd);
                    }
                }
                // E E E
                else if (CreatureMapItems[x].MapX - MyCreature.MapX == +3 && CreatureMapItems[x].MapY - MyCreature.MapY == -0)
                {
                    if (CreatureMapItems[x].Transparent == false || (CreatureMapItems[x].isDark(MyCreature) == true && ignoreDark == false))
                    {
                        //ADD TO HIDDEN
                        PointToAdd = new Point(MyCreature.MapX + 4, MyCreature.MapY - 0);
                        HiddenList.Add(PointToAdd);

                        //Check NE E E
                        for (int y = 0; y < CreatureMapItems.Count; y++)
                        {
                            if (CreatureMapItems[y].MapX - MyCreature.MapX == +3 && CreatureMapItems[y].MapY - MyCreature.MapY == -1)
                            {
                                if (CreatureMapItems[y].Transparent == false || (CreatureMapItems[y].isDark(MyCreature) == true && ignoreDark == false))
                                {
                                    //ADD TO HIDDEN
                                    PointToAdd = new Point(MyCreature.MapX + 4, MyCreature.MapY - 1);
                                    HiddenList.Add(PointToAdd);
                                }
                                break;
                            }
                        }
                        //CHECK SE E E
                        for (int z = 0; z < CreatureMapItems.Count; z++)
                        {
                            if (CreatureMapItems[z].MapX - MyCreature.MapX == +3 && CreatureMapItems[z].MapY - MyCreature.MapY == +1)
                            {
                                if (CreatureMapItems[z].Transparent == false || (CreatureMapItems[z].isDark(MyCreature) == true && ignoreDark == false))
                                {
                                    //ADD TO HIDDEN
                                    PointToAdd = new Point(MyCreature.MapX + 4, MyCreature.MapY + 1);
                                    HiddenList.Add(PointToAdd);
                                }
                                break;
                            }
                        }
                    }
                }
                //SE E E
                else if (CreatureMapItems[x].MapX - MyCreature.MapX == +3 && CreatureMapItems[x].MapY - MyCreature.MapY == +1)
                {
                    if (CreatureMapItems[x].Transparent == false || (CreatureMapItems[x].isDark(MyCreature) == true && ignoreDark == false))
                    {
                        //ADD TO HIDDEN
                        PointToAdd = new Point(MyCreature.MapX + 4, MyCreature.MapY + 2);
                        HiddenList.Add(PointToAdd);
                    }
                }
                //SE SE E
                else if (CreatureMapItems[x].MapX - MyCreature.MapX == +3 && CreatureMapItems[x].MapY - MyCreature.MapY == +2)
                {
                    if (CreatureMapItems[x].Transparent == false || (CreatureMapItems[x].isDark(MyCreature) == true && ignoreDark == false))
                    {
                        //ADD TO HIDDEN
                        PointToAdd = new Point(MyCreature.MapX + 4, MyCreature.MapY + 3);
                        HiddenList.Add(PointToAdd);
                    }
                }
                //SE SE SE
                else if (CreatureMapItems[x].MapX - MyCreature.MapX == +3 && CreatureMapItems[x].MapY - MyCreature.MapY == +3)
                {
                    if (CreatureMapItems[x].Transparent == false || (CreatureMapItems[x].isDark(MyCreature) == true && ignoreDark == false))
                    {
                        //ADD TO HIDDEN
                        PointToAdd = new Point(MyCreature.MapX + 4, MyCreature.MapY + 4);
                        HiddenList.Add(PointToAdd);
                    }
                }
                //SE SE S
                else if (CreatureMapItems[x].MapX - MyCreature.MapX == +2 && CreatureMapItems[x].MapY - MyCreature.MapY == +3)
                {
                    if (CreatureMapItems[x].Transparent == false || (CreatureMapItems[x].isDark(MyCreature) == true && ignoreDark == false))
                    {
                        //ADD TO HIDDEN
                        PointToAdd = new Point(MyCreature.MapX + 3, MyCreature.MapY + 4);
                        HiddenList.Add(PointToAdd);
                    }
                }
                //SE S S
                else if (CreatureMapItems[x].MapX - MyCreature.MapX == +1 && CreatureMapItems[x].MapY - MyCreature.MapY == +3)
                {
                    if (CreatureMapItems[x].Transparent == false || (CreatureMapItems[x].isDark(MyCreature) == true && ignoreDark == false))
                    {
                        //ADD TO HIDDEN
                        PointToAdd = new Point(MyCreature.MapX + 2, MyCreature.MapY + 4);
                        HiddenList.Add(PointToAdd);
                    }
                }
                //S S S
                else if (CreatureMapItems[x].MapX - MyCreature.MapX == +0 && CreatureMapItems[x].MapY - MyCreature.MapY == +3)
                {
                    if (CreatureMapItems[x].Transparent == false || (CreatureMapItems[x].isDark(MyCreature) == true && ignoreDark == false))
                    {
                        //ADD TO HIDDEN
                        PointToAdd = new Point(MyCreature.MapX + 0, MyCreature.MapY + 4);
                        HiddenList.Add(PointToAdd);

                        //Check SE S S
                        for (int y = 0; y < CreatureMapItems.Count; y++)
                        {
                            if (CreatureMapItems[y].MapX - MyCreature.MapX == +1 && CreatureMapItems[y].MapY - MyCreature.MapY == +3)
                            {
                                if (CreatureMapItems[y].Transparent == false || (CreatureMapItems[y].isDark(MyCreature) == true && ignoreDark == false))
                                {
                                    //ADD TO HIDDEN
                                    PointToAdd = new Point(MyCreature.MapX + 1, MyCreature.MapY + 4);
                                    HiddenList.Add(PointToAdd);
                                }
                                break;
                            }
                        }
                        //CHECK SE E E
                        for (int z = 0; z < CreatureMapItems.Count; z++)
                        {
                            if (CreatureMapItems[z].MapX - MyCreature.MapX == -1 && CreatureMapItems[z].MapY - MyCreature.MapY == +3)
                            {
                                if (CreatureMapItems[z].Transparent == false || (CreatureMapItems[z].isDark(MyCreature) == true && ignoreDark == false))
                                {
                                    //ADD TO HIDDEN
                                    PointToAdd = new Point(MyCreature.MapX - 1, MyCreature.MapY + 4);
                                    HiddenList.Add(PointToAdd);
                                }
                                break;
                            }
                        }
                    }
                }
                // SW S S
                else if (CreatureMapItems[x].MapX - MyCreature.MapX == -1 && CreatureMapItems[x].MapY - MyCreature.MapY == +3)
                {
                    if (CreatureMapItems[x].Transparent == false || (CreatureMapItems[x].isDark(MyCreature) == true && ignoreDark == false))
                    {
                        //ADD TO HIDDEN
                        PointToAdd = new Point(MyCreature.MapX - 2, MyCreature.MapY + 4);
                        HiddenList.Add(PointToAdd);
                    }
                }
                // SW SW S
                else if (CreatureMapItems[x].MapX - MyCreature.MapX == -2 && CreatureMapItems[x].MapY - MyCreature.MapY == +3)
                {
                    if (CreatureMapItems[x].Transparent == false || (CreatureMapItems[x].isDark(MyCreature) == true && ignoreDark == false))
                    {
                        //ADD TO HIDDEN
                        PointToAdd = new Point(MyCreature.MapX - 3, MyCreature.MapY + 4);
                        HiddenList.Add(PointToAdd);
                    }
                }
                // SW SW SW
                else if (CreatureMapItems[x].MapX - MyCreature.MapX == -3 && CreatureMapItems[x].MapY - MyCreature.MapY == +3)
                {
                    if (CreatureMapItems[x].Transparent == false || (CreatureMapItems[x].isDark(MyCreature) == true && ignoreDark == false))
                    {
                        //ADD TO HIDDEN
                        PointToAdd = new Point(MyCreature.MapX - 4, MyCreature.MapY + 4);
                        HiddenList.Add(PointToAdd);
                    }
                }
                // SW SW W
                else if (CreatureMapItems[x].MapX - MyCreature.MapX == -3 && CreatureMapItems[x].MapY - MyCreature.MapY == +2)
                {
                    if (CreatureMapItems[x].Transparent == false || (CreatureMapItems[x].isDark(MyCreature) == true && ignoreDark == false))
                    {
                        //ADD TO HIDDEN
                        PointToAdd = new Point(MyCreature.MapX - 4, MyCreature.MapY + 3);
                        HiddenList.Add(PointToAdd);
                    }
                }
                // SW W W
                else if (CreatureMapItems[x].MapX - MyCreature.MapX == -3 && CreatureMapItems[x].MapY - MyCreature.MapY == +1)
                {
                    if (CreatureMapItems[x].Transparent == false || (CreatureMapItems[x].isDark(MyCreature) == true && ignoreDark == false))
                    {
                        //ADD TO HIDDEN
                        PointToAdd = new Point(MyCreature.MapX - 4, MyCreature.MapY + 2);
                        HiddenList.Add(PointToAdd);
                    }
                }
                // W W W
                else if (CreatureMapItems[x].MapX - MyCreature.MapX == -3 && CreatureMapItems[x].MapY - MyCreature.MapY == +0)
                {
                    if (CreatureMapItems[x].Transparent == false || (CreatureMapItems[x].isDark(MyCreature) == true && ignoreDark == false))
                    {
                        //ADD TO HIDDEN
                        PointToAdd = new Point(MyCreature.MapX - 4, MyCreature.MapY + 0);
                        HiddenList.Add(PointToAdd);

                        //Check SW W W
                        for (int y = 0; y < CreatureMapItems.Count; y++)
                        {
                            if (CreatureMapItems[y].MapX - MyCreature.MapX == -3 && CreatureMapItems[y].MapY - MyCreature.MapY == +1)
                            {
                                if (CreatureMapItems[y].Transparent == false || (CreatureMapItems[y].isDark(MyCreature) == true && ignoreDark == false))
                                {
                                    //ADD TO HIDDEN
                                    PointToAdd = new Point(MyCreature.MapX - 4, MyCreature.MapY + 1);
                                    HiddenList.Add(PointToAdd);
                                }
                                break;
                            }
                        }
                        //CHECK NW W W
                        for (int y = 0; y < CreatureMapItems.Count; y++)
                        {
                            if (CreatureMapItems[y].MapX - MyCreature.MapX == -3 && CreatureMapItems[y].MapY - MyCreature.MapY == -1)
                            {
                                if (CreatureMapItems[y].Transparent == false || (CreatureMapItems[y].isDark(MyCreature) == true && ignoreDark == false))
                                {
                                    //ADD TO HIDDEN
                                    PointToAdd = new Point(MyCreature.MapX - 4, MyCreature.MapY - 1);
                                    HiddenList.Add(PointToAdd);
                                }
                                break;
                            }
                        }
                    }
                }
                //NW W W
                else if (CreatureMapItems[x].MapX - MyCreature.MapX == -3 && CreatureMapItems[x].MapY - MyCreature.MapY == -1)
                {
                    if (CreatureMapItems[x].Transparent == false || (CreatureMapItems[x].isDark(MyCreature) == true && ignoreDark == false))
                    {
                        //ADD TO HIDDEN
                        PointToAdd = new Point(MyCreature.MapX - 4, MyCreature.MapY - 2);
                        HiddenList.Add(PointToAdd);
                    }
                }
                //NW NW W
                else if (CreatureMapItems[x].MapX - MyCreature.MapX == -3 && CreatureMapItems[x].MapY - MyCreature.MapY == -2)
                {
                    if (CreatureMapItems[x].Transparent == false || (CreatureMapItems[x].isDark(MyCreature) == true && ignoreDark == false))
                    {
                        //ADD TO HIDDEN
                        PointToAdd = new Point(MyCreature.MapX - 4, MyCreature.MapY - 3);
                        HiddenList.Add(PointToAdd);
                    }
                }
            }
            return HiddenList;
        }

    }//End Class
}//End Namespace
